$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r63668 - in sandbox/geometry/boost/geometry/extensions/contrib: . ttmath
From: barend.gehrels_at_[hidden]
Date: 2010-07-05 13:06:08
Author: barendgehrels
Date: 2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
New Revision: 63668
URL: http://svn.boost.org/trac/boost/changeset/63668
Log:
Added (possibly temporary) ttmath as extension / contribution, for testing high precision
Added:
   sandbox/geometry/boost/geometry/extensions/contrib/
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmath.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathbig.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathint.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathparser.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm   (contents, props changed)
   sandbox/geometry/boost/geometry/extensions/contrib/ttmath_stub.hpp   (contents, props changed)
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmath.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmath.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,2835 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathmathtt
+#define headerfilettmathmathtt
+
+/*!
+	\file ttmath.h
+    \brief Mathematics functions.
+*/
+
+#ifdef _MSC_VER
+//warning C4127: conditional expression is constant
+#pragma warning( disable: 4127 )
+//warning C4702: unreachable code
+#pragma warning( disable: 4702 )
+//warning C4800: forcing value to bool 'true' or 'false' (performance warning)
+#pragma warning( disable: 4800 )
+#endif
+
+
+#include "ttmathbig.h"
+#include "ttmathobjects.h"
+
+
+namespace ttmath
+{
+	/*
+ 	 *
+	 *  functions defined here are used only with Big<> types
+	 *
+	 *
+	 */
+
+
+	/*
+ 	 *
+	 *  functions for rounding
+	 *
+	 *
+	 */
+
+
+	/*!
+		this function skips the fraction from x
+		e.g  2.2  = 2
+		     2.7  = 2
+			 -2.2 = 2
+			 -2.7 = 2
+	*/
+	template<class ValueType>
+	ValueType SkipFraction(const ValueType & x)
+	{
+		ValueType result( x );
+		result.SkipFraction();
+
+	return result;
+	}
+
+
+	/*!
+		this function rounds to the nearest integer value
+		e.g  2.2  = 2
+		     2.7  = 3
+			 -2.2 = -2
+			 -2.7 = -3
+	*/
+	template<class ValueType>
+	ValueType Round(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType result( x );
+		uint c = result.Round();
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+
+	/*!
+		this function returns a value representing the smallest integer
+		that is greater than or equal to x
+
+		Ceil(-3.7) = -3
+		Ceil(-3.1) = -3
+		Ceil(-3.0) = -3
+		Ceil(4.0)  = 4
+		Ceil(4.2)  = 5
+		Ceil(4.8)  = 5
+	*/
+	template<class ValueType>
+	ValueType Ceil(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType result(x);
+		uint c = 0;
+
+		result.SkipFraction();
+
+		if( result != x )
+		{
+			// x is with fraction
+			// if x is negative we don't have to do anything
+			if( !x.IsSign() )
+			{
+				ValueType one;
+				one.SetOne();
+
+				c += result.Add(one);
+			}
+		}
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;	
+	}
+
+
+	/*!
+		this function returns a value representing the largest integer
+		that is less than or equal to x
+
+		Floor(-3.6) = -4
+		Floor(-3.1) = -4
+		Floor(-3)   = -3
+		Floor(2)    = 2
+		Floor(2.3)  = 2
+		Floor(2.8)  = 2
+	*/
+	template<class ValueType>
+	ValueType Floor(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType result(x);
+		uint c = 0;
+
+		result.SkipFraction();
+
+		if( result != x )
+		{
+			// x is with fraction
+			// if x is positive we don't have to do anything
+			if( x.IsSign() )
+			{
+				ValueType one;
+				one.SetOne();
+
+				c += result.Sub(one);
+			}
+		}
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;	
+	}
+
+
+
+	/*
+ 	 *
+	 *  logarithms and the exponent
+	 *
+	 *
+	 */
+
+	
+	/*!
+		this function calculates the natural logarithm (logarithm with the base 'e')
+	*/
+	template<class ValueType>
+	ValueType Ln(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType 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 function calculates the logarithm
+	*/
+	template<class ValueType>
+	ValueType Log(const ValueType & x, const ValueType & base, ErrorCode * err = 0)
+	{
+		if( x.IsNan() || base.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return ValueType(); // default NaN
+		}
+
+		ValueType result;
+		uint state = result.Log(x, base);
+
+		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 function calculates the expression e^x
+	*/
+	template<class ValueType>
+	ValueType Exp(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType result;
+		uint c = result.Exp(x);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+	*
+	*	trigonometric functions
+	*
+	*/
+
+
+	/*
+		this namespace consists of auxiliary functions
+		(something like 'private' in a class)
+	*/
+	namespace auxiliaryfunctions
+	{
+
+	/*!
+		an auxiliary function for calculating the Sine
+		(you don't have to call this function) 
+	*/
+	template<class ValueType>
+	uint PrepareSin(ValueType & x, bool & change_sign)
+	{
+	ValueType 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.Mod(temp) )
+			return 1;
+		
+
+		// 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;
+		}
+
+	return 0;
+	}
+
+	
+	/*!
+		an auxiliary function for calculating the Sine
+		(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<class ValueType>
+	ValueType Sin0pi05(const ValueType & x)
+	{
+	ValueType result;
+	ValueType numerator, denominator;
+	ValueType d_numerator, d_denominator;
+	ValueType 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
+			ValueType pi05;
+			pi05.Set05Pi();
+
+			temp = x;
+			temp.Sub( pi05 );
+			d_numerator = temp;
+			d_numerator.Mul( temp );
+
+			d_denominator = one;
+		}
+
+		uint c = 0;
+		bool addition = false;
+
+		old_result = result;
+		for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++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 break 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;
+	}
+
+	} // namespace auxiliaryfunctions
+
+
+
+	/*!
+		this function calculates the Sine
+	*/
+	template<class ValueType>
+	ValueType Sin(ValueType x, ErrorCode * err = 0)
+	{
+	using namespace auxiliaryfunctions;
+
+	ValueType one, result;
+	bool change_sign;	
+	
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		if( err )
+			*err = err_ok;
+
+		if( PrepareSin( x, change_sign ) )
+		{
+			// x is too big, we cannnot reduce the 2*PI period
+			// prior to version 0.8.5 the result was zero
+			
+			// result has NaN flag set by default
+
+			if( err )
+				*err = err_overflow; // maybe another error code? err_improper_argument?
+
+		return result; // NaN is set by default
+		}
+
+		result = Sin0pi05( x );
+	
+		one.SetOne();
+
+		// after calculations there can be small distortions in the result
+		if( result > one )
+			result = one;
+		else
+		if( result.IsSign() )
+			// we've calculated the sin from <0, pi/2> and the result
+			// should be positive
+			result.SetZero();
+
+		if( change_sign )
+			result.ChangeSign();	
+		
+	return result;
+	}
+
+	
+	/*!
+		this function calulates the Cosine
+		we're using the formula cos(x) = sin(x + PI/2)
+	*/
+	template<class ValueType>
+	ValueType Cos(ValueType x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType pi05;
+		pi05.Set05Pi();
+
+		uint c = x.Add( pi05 );
+
+		if( c )
+		{
+			if( err )
+				*err = err_overflow;
+	
+		return ValueType(); // result is undefined (NaN is set by default)
+		}
+
+	return Sin(x, err);
+	}
+	
+
+	/*!
+		this function calulates the Tangent
+		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 preciser
+		because Tan receives its values from -infinity to +infinity
+		and when we calculate it from any series then we can make
+		a greater mistake than calculating 'sin/cos'
+	*/
+	template<class ValueType>
+	ValueType Tan(const ValueType & x, ErrorCode * err = 0)
+	{
+		ValueType result = Cos(x, err);
+		
+		if( err && *err != err_ok )
+			return result;
+
+		if( result.IsZero() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+			result.SetNan();
+
+		return result;
+		}
+
+	return Sin(x, err) / result;
+	}
+
+
+	/*!
+		this function calulates the Tangent
+		look at the description of Tan(...)
+
+		(the abbreviation of Tangent can be 'tg' as well)
+	*/
+	template<class ValueType>
+	ValueType Tg(const ValueType & x, ErrorCode * err = 0)
+	{
+		return Tan(x, err);
+	}
+
+
+	/*!
+		this function calulates the Cotangent
+		we're using the formula tan(x) = cos(x) / sin(x)
+
+		(why do we make it in this way? 
+		look at information in Tan() function)
+	*/
+	template<class ValueType>
+	ValueType Cot(const ValueType & x, ErrorCode * err = 0)
+	{
+		ValueType result = Sin(x, err);
+
+		if( err && *err != err_ok )
+			return result;
+
+		if( result.IsZero() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+			result.SetNan();
+
+		return result;
+		}
+	
+	return Cos(x, err) / result;
+	}
+
+
+	/*!
+		this function calulates the Cotangent
+		look at the description of Cot(...)
+
+		(the abbreviation of Cotangent can be 'ctg' as well)
+	*/
+	template<class ValueType>
+	ValueType Ctg(const ValueType & x, ErrorCode * err = 0)
+	{
+		return Cot(x, err);
+	}
+
+
+	/*
+ 	 *
+	 *  inverse trigonometric functions
+	 *
+	 *
+	 */
+
+	namespace auxiliaryfunctions
+	{
+
+	/*!
+		an auxiliary function for calculating the Arc Sine
+
+		we're calculating asin from the following formula:
+		asin(x) = x + (1*x^3)/(2*3) + (1*3*x^5)/(2*4*5) + (1*3*5*x^7)/(2*4*6*7) + ... 
+		where abs(x) <= 1
+
+		we're using this formula when x is from <0, 1/2>
+	*/
+	template<class ValueType>
+	ValueType ASin_0(const ValueType & x)
+	{
+	ValueType nominator, denominator, nominator_add, nominator_x, denominator_add, denominator_x;
+	ValueType two, result(x), x2(x);
+	ValueType nominator_temp, denominator_temp, old_result = result;
+	uint c = 0;
+
+	x2.Mul(x);
+	two = 2;
+
+	nominator.SetOne();
+	denominator     = two;
+	nominator_add   = nominator;
+	denominator_add = denominator;
+	nominator_x     = x;
+	denominator_x   = 3;
+
+		for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+		{
+			c += nominator_x.Mul(x2);
+			nominator_temp = nominator_x;	
+			c += nominator_temp.Mul(nominator);
+			denominator_temp = denominator;
+			c += denominator_temp.Mul(denominator_x);
+			c += nominator_temp.Div(denominator_temp);
+
+			// if there is a carry somewhere we only break the calculating
+			// the result should be ok -- it's from <-pi/2, pi/2>
+			if( c ) 
+				break;
+
+			result.Add(nominator_temp);
+			
+			if( result == old_result )
+				 // there's no sense to calculate more
+				break;
+
+			old_result = result;
+
+
+			c += nominator_add.Add(two);
+			c += denominator_add.Add(two);
+			c += nominator.Mul(nominator_add);
+			c += denominator.Mul(denominator_add);
+			c += denominator_x.Add(two);
+		}
+
+	return result;
+	}
+
+
+
+	/*!
+		an auxiliary function for calculating the Arc Sine
+
+		we're calculating asin from the following formula:
+		asin(x) = pi/2 - sqrt(2)*sqrt(1-x) * asin_temp
+		asin_temp = 1 + (1*(1-x))/((2*3)*(2)) + (1*3*(1-x)^2)/((2*4*5)*(4)) + (1*3*5*(1-x)^3)/((2*4*6*7)*(8)) + ... 
+
+		where abs(x) <= 1
+
+		we're using this formula when x is from (1/2, 1>
+	*/
+	template<class ValueType>
+	ValueType ASin_1(const ValueType & x)
+	{
+	ValueType nominator, denominator, nominator_add, nominator_x, nominator_x_add, denominator_add, denominator_x;
+	ValueType denominator2;
+	ValueType one, two, result;
+	ValueType nominator_temp, denominator_temp, old_result;
+	uint c = 0;
+
+	two = 2;
+
+	one.SetOne();
+	nominator		= one;
+	result			= one;
+	old_result		= result;
+	denominator     = two;
+	nominator_add   = nominator;
+	denominator_add = denominator;
+	nominator_x     = one;
+	nominator_x.Sub(x);
+	nominator_x_add = nominator_x;
+	denominator_x   = 3;
+	denominator2	= two;
+
+
+		for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+		{
+			nominator_temp = nominator_x;	
+			c += nominator_temp.Mul(nominator);
+			denominator_temp = denominator;
+			c += denominator_temp.Mul(denominator_x);
+			c += denominator_temp.Mul(denominator2);
+			c += nominator_temp.Div(denominator_temp);
+
+			// if there is a carry somewhere we only break the calculating
+			// the result should be ok -- it's from <-pi/2, pi/2>
+			if( c ) 
+				break;
+
+			result.Add(nominator_temp);
+			
+			if( result == old_result )
+				 // there's no sense to calculate more
+				break;
+
+			old_result = result;
+
+			c += nominator_x.Mul(nominator_x_add);
+			c += nominator_add.Add(two);
+			c += denominator_add.Add(two);
+			c += nominator.Mul(nominator_add);
+			c += denominator.Mul(denominator_add);
+			c += denominator_x.Add(two);
+			c += denominator2.Mul(two);
+		}
+
+		
+		nominator_x_add.exponent.AddOne(); // *2
+		one.exponent.SubOne(); // =0.5
+		nominator_x_add.Pow(one); // =sqrt(nominator_x_add)
+		result.Mul(nominator_x_add);
+
+		one.Set05Pi();
+		one.Sub(result);
+
+	return one;
+	}
+
+
+	} // namespace auxiliaryfunctions
+
+
+	/*!
+		this function calculates the Arc Sine
+		x is from <-1,1>
+	*/
+	template<class ValueType>
+	ValueType ASin(ValueType x, ErrorCode * err = 0)
+	{
+	using namespace auxiliaryfunctions;
+
+		ValueType result, one;
+		one.SetOne();
+		bool change_sign = false;
+
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		if( x.GreaterWithoutSignThan(one) )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+			return result; // NaN is set by default
+		}
+
+		if( x.IsSign() )
+		{
+			change_sign = true;
+			x.Abs();
+		}
+
+		one.exponent.SubOne(); // =0.5
+
+		// asin(-x) = -asin(x)
+		if( x.GreaterWithoutSignThan(one) )
+			result = ASin_1(x);	
+		else
+			result = ASin_0(x);
+
+		if( change_sign )
+			result.ChangeSign();
+
+		if( err )
+			*err = err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		this function calculates the Arc Cosine
+
+		we're using the formula:
+		acos(x) = pi/2 - asin(x)
+	*/
+	template<class ValueType>
+	ValueType ACos(const ValueType & x, ErrorCode * err = 0)
+	{
+	ValueType temp;
+
+		temp.Set05Pi();
+		temp.Sub(ASin(x, err));
+
+	return temp;
+	}
+
+
+
+	namespace auxiliaryfunctions
+	{
+
+	/*!
+		an auxiliary function for calculating the Arc Tangent
+
+		arc tan (x) where x is in <0; 0.5)
+		(x can be in (-0.5 ; 0.5) too)
+
+		we're using the Taylor series expanded in zero:
+		atan(x) = x - (x^3)/3 + (x^5)/5 - (x^7)/7 + ...
+	*/
+	template<class ValueType>
+	ValueType ATan0(const ValueType & x)
+	{
+		ValueType nominator, denominator, nominator_add, denominator_add, temp;
+		ValueType result, old_result;
+		bool adding = false;
+		uint c = 0;
+
+		result        = x;
+		old_result    = result;
+		nominator     = x;
+		nominator_add = x;
+		nominator_add.Mul(x);
+
+		denominator.SetOne();
+		denominator_add = 2;
+
+		for(uint i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+		{
+			c += nominator.Mul(nominator_add);
+			c += denominator.Add(denominator_add);
+	
+			temp = nominator;
+			c += temp.Div(denominator);
+
+			if( c )
+				// the result should be ok
+				break;
+
+			if( adding )
+				result.Add(temp);
+			else
+				result.Sub(temp);
+
+			if( result == old_result )
+				 // there's no sense to calculate more
+				break;
+
+			old_result = result;
+			adding     = !adding;
+		}
+
+	return result;
+	}
+
+
+	/*!
+		an auxiliary function for calculating the Arc Tangent
+
+		where x is in <0 ; 1>
+	*/
+	template<class ValueType>
+	ValueType ATan01(const ValueType & x)
+	{
+		ValueType half;
+		half.Set05();
+
+		/*
+			it would be better if we chose about sqrt(2)-1=0.41... instead of 0.5 here
+
+			because as you can see below:
+			when x = sqrt(2)-1
+			abs(x) = abs( (x-1)/(1+x) )
+			so when we're calculating values around x
+			then they will be better converged to each other
+
+			for example if we have x=0.4999 then during calculating ATan0(0.4999)
+			we have to make about 141 iterations but when we have x=0.5
+			then during calculating ATan0( (x-1)/(1+x) ) we have to make 
+			only about 89 iterations (both for Big<3,9>)
+
+			in the future this 0.5 can be changed
+		*/
+		if( x.SmallerWithoutSignThan(half) )
+			return ATan0(x);
+
+
+		/*
+			x>=0.5 and x<=1
+			(x can be even smaller than 0.5)
+
+			y = atac(x)
+			x = tan(y)
+
+			tan(y-b) = (tan(y)-tab(b)) / (1+tan(y)*tan(b))
+			y-b      = atan( (tan(y)-tab(b)) / (1+tan(y)*tan(b)) )
+			y        = b + atan( (x-tab(b)) / (1+x*tan(b)) )
+
+			let b = pi/4
+			tan(b) = tan(pi/4) = 1
+			y = pi/4 + atan( (x-1)/(1+x) )
+
+			so
+			atac(x) = pi/4 + atan( (x-1)/(1+x) )
+			when x->1 (x converges to 1) the (x-1)/(1+x) -> 0
+			and we can use ATan0() function here
+		*/
+
+		ValueType n(x),d(x),one,result;
+
+		one.SetOne();
+		n.Sub(one);
+		d.Add(one);
+		n.Div(d);
+
+		result = ATan0(n);
+
+		n.Set05Pi();
+		n.exponent.SubOne(); // =pi/4
+		result.Add(n);
+
+	return result;
+	}
+
+
+	/*!
+		an auxiliary function for calculating the Arc Tangent
+		where x > 1
+
+		we're using the formula:
+		atan(x) = pi/2 - atan(1/x) for x>0
+	*/
+	template<class ValueType>
+	ValueType ATanGreaterThanPlusOne(const ValueType & x)
+	{
+	ValueType temp, atan;
+
+		temp.SetOne();
+		
+		if( temp.Div(x) )
+		{
+			// if there was a carry here that means x is very big
+			// and atan(1/x) fast converged to 0
+			atan.SetZero();
+		}
+		else
+			atan = ATan01(temp);
+		
+		temp.Set05Pi();
+		temp.Sub(atan);
+
+	return temp;
+	}
+
+	} // namespace auxiliaryfunctions
+
+
+	/*!
+		this function calculates the Arc Tangent
+	*/
+	template<class ValueType>
+	ValueType ATan(ValueType x)
+	{
+	using namespace auxiliaryfunctions;
+
+		ValueType one, result;
+		one.SetOne();
+		bool change_sign = false;
+
+		if( x.IsNan() )
+			return result; // NaN is set by default
+
+		// if x is negative we're using the formula:
+		// atan(-x) = -atan(x)
+		if( x.IsSign() )
+		{
+			change_sign = true;
+			x.Abs();
+		}
+
+		if( x.GreaterWithoutSignThan(one) )
+			result = ATanGreaterThanPlusOne(x);
+		else
+			result = ATan01(x);
+
+		if( change_sign )
+			result.ChangeSign();
+
+	return result;
+	}
+
+
+	/*!
+		this function calculates the Arc Tangent
+		look at the description of ATan(...)
+
+		(the abbreviation of Arc Tangent can be 'atg' as well)
+	*/
+	template<class ValueType>
+	ValueType ATg(const ValueType & x)
+	{
+		return ATan(x);
+	}
+
+
+	/*!
+		this function calculates the Arc Cotangent
+	
+		we're using the formula:
+		actan(x) = pi/2 - atan(x)
+	*/
+	template<class ValueType>
+	ValueType ACot(const ValueType & x)
+	{
+	ValueType result;
+
+		result.Set05Pi();
+		result.Sub(ATan(x));
+
+	return result;
+	}
+
+
+	/*!
+		this function calculates the Arc Cotangent
+		look at the description of ACot(...)
+
+		(the abbreviation of Arc Cotangent can be 'actg' as well)
+	*/
+	template<class ValueType>
+	ValueType ACtg(const ValueType & x)
+	{
+		return ACot(x);
+	}
+
+
+	/*
+ 	 *
+	 *  hyperbolic functions
+	 *
+	 *
+	 */
+
+
+	/*!
+		this function calculates the Hyperbolic Sine
+
+		we're using the formula sinh(x)= ( e^x - e^(-x) ) / 2
+	*/
+	template<class ValueType>
+	ValueType Sinh(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType ex, emx;
+		uint c = 0;
+
+		c += ex.Exp(x);
+		c += emx.Exp(-x);
+
+		c += ex.Sub(emx);
+		c += ex.exponent.SubOne();
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return ex;
+	}
+
+
+	/*!
+		this function calculates the Hyperbolic Cosine
+
+		we're using the formula cosh(x)= ( e^x + e^(-x) ) / 2
+	*/
+	template<class ValueType>
+	ValueType Cosh(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType ex, emx;
+		uint c = 0;
+
+		c += ex.Exp(x);
+		c += emx.Exp(-x);
+
+		c += ex.Add(emx);
+		c += ex.exponent.SubOne();
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return ex;
+	}
+
+
+	/*!
+		this function calculates the Hyperbolic Tangent
+
+		we're using the formula tanh(x)= ( e^x - e^(-x) ) / ( e^x + e^(-x) )
+	*/
+	template<class ValueType>
+	ValueType Tanh(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType ex, emx, nominator, denominator;
+		uint c = 0;
+
+		c += ex.Exp(x);
+		c += emx.Exp(-x);
+
+		nominator = ex;
+		c += nominator.Sub(emx);
+		denominator = ex;
+		c += denominator.Add(emx);
+		
+		c += nominator.Div(denominator);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return nominator;
+	}
+
+
+	/*!
+		this function calculates the Hyperbolic Tangent
+		look at the description of Tanh(...)
+
+		(the abbreviation of Hyperbolic Tangent can be 'tgh' as well)
+	*/
+	template<class ValueType>
+	ValueType Tgh(const ValueType & x, ErrorCode * err = 0)
+	{
+		return Tanh(x, err);
+	}
+
+	/*!
+		this function calculates the Hyperbolic Cotangent
+
+		we're using the formula coth(x)= ( e^x + e^(-x) ) / ( e^x - e^(-x) )
+	*/
+	template<class ValueType>
+	ValueType Coth(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		if( x.IsZero() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+			return ValueType(); // NaN is set by default
+		}
+
+		ValueType ex, emx, nominator, denominator;
+		uint c = 0;
+
+		c += ex.Exp(x);
+		c += emx.Exp(-x);
+
+		nominator = ex;
+		c += nominator.Add(emx);
+		denominator = ex;
+		c += denominator.Sub(emx);
+		
+		c += nominator.Div(denominator);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return nominator;
+	}
+
+
+	/*!
+		this function calculates the Hyperbolic Cotangent
+		look at the description of Coth(...)
+
+		(the abbreviation of Hyperbolic Cotangent can be 'ctgh' as well)
+	*/
+	template<class ValueType>
+	ValueType Ctgh(const ValueType & x, ErrorCode * err = 0)
+	{
+		return Coth(x, err);
+	}
+
+
+	/*
+ 	 *
+	 *  inverse hyperbolic functions
+	 *
+	 *
+	 */
+
+
+	/*!
+		inverse hyperbolic sine
+
+		asinh(x) = ln( x + sqrt(x^2 + 1) )
+	*/
+	template<class ValueType>
+	ValueType ASinh(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType xx(x), one, result;
+		uint c = 0;
+		one.SetOne();
+
+		c += xx.Mul(x);
+		c += xx.Add(one);
+		one.exponent.SubOne(); // one=0.5
+		// xx is >= 1 
+		c += xx.PowFrac(one); // xx=sqrt(xx)
+		c += xx.Add(x);
+		c += result.Ln(xx); // xx > 0
+
+		// here can only be a carry
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		inverse hyperbolic cosine
+
+		acosh(x) = ln( x + sqrt(x^2 - 1) )  x in <1, infinity)
+	*/
+	template<class ValueType>
+	ValueType ACosh(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType xx(x), one, result;
+		uint c = 0;
+		one.SetOne();
+
+		if( x < one )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		c += xx.Mul(x);
+		c += xx.Sub(one);
+		// xx is >= 0
+		// we can't call a PowFrac when the 'x' is zero
+		// if x is 0 the sqrt(0) is 0
+		if( !xx.IsZero() )
+		{
+			one.exponent.SubOne(); // one=0.5
+			c += xx.PowFrac(one); // xx=sqrt(xx)
+		}
+		c += xx.Add(x);
+		c += result.Ln(xx); // xx >= 1
+
+		// here can only be a carry
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		inverse hyperbolic tangent
+
+		atanh(x) = 0.5 * ln( (1+x) / (1-x) )  x in (-1, 1)
+	*/
+	template<class ValueType>
+	ValueType ATanh(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType nominator(x), denominator, one, result;
+		uint c = 0;
+		one.SetOne();
+
+		if( !x.SmallerWithoutSignThan(one) )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		c += nominator.Add(one);
+		denominator = one;
+		c += denominator.Sub(x);
+		c += nominator.Div(denominator);
+		c += result.Ln(nominator);
+		c += result.exponent.SubOne();
+
+		// here can only be a carry
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		inverse hyperbolic tantent
+	*/
+	template<class ValueType>
+	ValueType ATgh(const ValueType & x, ErrorCode * err = 0)
+	{
+		return ATanh(x, err);
+	}
+
+
+	/*!
+		inverse hyperbolic cotangent
+
+		acoth(x) = 0.5 * ln( (x+1) / (x-1) )  x in (-infinity, -1) or (1, infinity)
+	*/
+	template<class ValueType>
+	ValueType ACoth(const ValueType & x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return x; // NaN
+		}
+
+		ValueType nominator(x), denominator(x), one, result;
+		uint c = 0;
+		one.SetOne();
+
+		if( !x.GreaterWithoutSignThan(one) )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		c += nominator.Add(one);
+		c += denominator.Sub(one);
+		c += nominator.Div(denominator);
+		c += result.Ln(nominator);
+		c += result.exponent.SubOne();
+
+		// here can only be a carry
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		inverse hyperbolic cotantent
+	*/
+	template<class ValueType>
+	ValueType ACtgh(const ValueType & x, ErrorCode * err = 0)
+	{
+		return ACoth(x, err);
+	}
+
+
+
+
+
+	/*
+ 	 *
+	 *  functions for converting between degrees, radians and gradians
+	 *
+	 *
+	 */
+
+
+	/*!
+		this function converts degrees to radians
+		
+		it returns: x * pi / 180
+	*/
+	template<class ValueType>
+	ValueType DegToRad(const ValueType & x, ErrorCode * err = 0)
+	{
+	ValueType result, temp;
+	uint c = 0;
+
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		result = x;
+
+		// it is better to make division first and then multiplication
+		// the result is more accurate especially when x is: 90,180,270 or 360
+		temp = 180;
+		c += result.Div(temp);
+
+		temp.SetPi();
+		c += result.Mul(temp);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		this function converts radians to degrees
+		
+		it returns: x * 180 / pi
+	*/
+	template<class ValueType>
+	ValueType RadToDeg(const ValueType & x, ErrorCode * err = 0)
+	{
+	ValueType result, delimiter;
+	uint c = 0;
+
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		result = 180;
+		c += result.Mul(x);
+
+		delimiter.SetPi();
+		c += result.Div(delimiter);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		this function converts degrees in the long format into one value
+
+		long format: (degrees, minutes, seconds)
+		minutes and seconds must be greater than or equal zero
+
+		result: 
+		if d>=0 : result= d + ((s/60)+m)/60
+		if d<0  : result= d - ((s/60)+m)/60
+
+		((s/60)+m)/60 = (s+60*m)/3600 (second version is faster because 
+		there's only one division)
+
+		for example:
+		DegToDeg(10, 30, 0) = 10.5
+		DegToDeg(10, 24, 35.6)=10.4098(8)
+	*/
+	template<class ValueType>
+	ValueType DegToDeg(	const ValueType & d, const ValueType & m, const ValueType & s,
+						ErrorCode * err = 0)
+	{
+	ValueType delimiter, multipler;
+	uint c = 0;
+
+		if( d.IsNan() || m.IsNan() || s.IsNan() || m.IsSign() || s.IsSign() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return delimiter ; // NaN is set by default
+		}
+
+		multipler = 60;
+		delimiter = 3600;
+
+		c += multipler.Mul(m);
+		c += multipler.Add(s);
+		c += multipler.Div(delimiter);
+
+		if( d.IsSign() )
+			multipler.ChangeSign();
+
+		c += multipler.Add(d);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return multipler;
+	}
+
+
+	/*!
+		this function converts degrees in the long format to radians
+	*/
+	template<class ValueType>
+	ValueType DegToRad(	const ValueType & d, const ValueType & m, const ValueType & s,
+						ErrorCode * err = 0)
+	{
+		ValueType temp_deg = DegToDeg(d,m,s,err);
+
+		if( err && *err!=err_ok )
+			return temp_deg;
+
+	return DegToRad(temp_deg, err);
+	}
+
+
+	/*!
+		this function converts gradians to radians
+		
+		it returns: x * pi / 200
+	*/
+	template<class ValueType>
+	ValueType GradToRad(const ValueType & x, ErrorCode * err = 0)
+	{
+	ValueType result, temp;
+	uint c = 0;
+
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		result = x;
+
+		// it is better to make division first and then multiplication
+		// the result is more accurate especially when x is: 100,200,300 or 400
+		temp = 200;
+		c += result.Div(temp);
+
+		temp.SetPi();
+		c += result.Mul(temp);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		this function converts radians to gradians
+		
+		it returns: x * 200 / pi
+	*/
+	template<class ValueType>
+	ValueType RadToGrad(const ValueType & x, ErrorCode * err = 0)
+	{
+	ValueType result, delimiter;
+	uint c = 0;
+
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		result = 200;
+		c += result.Mul(x);
+
+		delimiter.SetPi();
+		c += result.Div(delimiter);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		this function converts degrees to gradians
+		
+		it returns: x * 200 / 180
+	*/
+	template<class ValueType>
+	ValueType DegToGrad(const ValueType & x, ErrorCode * err = 0)
+	{
+	ValueType result, temp;
+	uint c = 0;
+
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		result = x;
+
+		temp = 200;
+		c += result.Mul(temp);
+
+		temp = 180;
+		c += result.Div(temp);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+	/*!
+		this function converts degrees in the long format to gradians
+	*/
+	template<class ValueType>
+	ValueType DegToGrad( const ValueType & d, const ValueType & m, const ValueType & s,
+						 ErrorCode * err = 0)
+	{
+		ValueType temp_deg = DegToDeg(d,m,s,err);
+
+		if( err && *err!=err_ok )
+			return temp_deg;
+
+	return DegToGrad(temp_deg, err);
+	}
+
+
+	/*!
+		this function converts degrees to gradians
+		
+		it returns: x * 180 / 200
+	*/
+	template<class ValueType>
+	ValueType GradToDeg(const ValueType & x, ErrorCode * err = 0)
+	{
+	ValueType result, temp;
+	uint c = 0;
+
+		if( x.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		result = x;
+
+		temp = 180;
+		c += result.Mul(temp);
+
+		temp = 200;
+		c += result.Div(temp);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return result;
+	}
+
+
+
+
+	/*
+ 	 *
+	 *  another functions
+	 *
+	 *
+	 */
+
+
+	/*!
+		this function calculates the square root
+
+		Sqrt(9) = 3
+	*/
+	template<class ValueType>
+	ValueType Sqrt(ValueType x, ErrorCode * err = 0)
+	{
+		if( x.IsNan() || x.IsSign() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return ValueType(); // NaN is set by default
+		}
+
+		uint c = x.Sqrt();
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return x;
+	}
+
+
+
+	namespace auxiliaryfunctions
+	{
+
+	template<class ValueType>
+	bool RootCheckIndexSign(ValueType & x, const ValueType & index, ErrorCode * err)
+	{
+		if( index.IsSign() )
+		{
+			// index cannot be negative
+			if( err )
+				*err = err_improper_argument;
+
+			x.SetNan();
+
+		return true;
+		}
+
+	return false;
+	}
+
+
+	template<class ValueType>
+	bool RootCheckIndexZero(ValueType & x, const ValueType & index, ErrorCode * err)
+	{
+		if( index.IsZero() )
+		{
+			if( x.IsZero() )
+			{
+				// there isn't root(0;0) - we assume it's not defined
+				if( err )
+					*err = err_improper_argument;
+
+				x.SetNan();
+
+			return true;
+			}
+	
+			// root(x;0) is 1 (if x!=0)
+			x.SetOne();
+
+			if( err )
+				*err = err_ok;
+
+		return true;
+		}
+
+	return false;
+	}
+
+
+	template<class ValueType>
+	bool RootCheckIndexOne(const ValueType & index, ErrorCode * err)
+	{
+		ValueType one;
+		one.SetOne();
+
+		if( index == one )
+		{
+			//root(x;1) is x
+			// we do it because if we used the PowFrac function
+			// we would lose the precision
+			if( err )
+				*err = err_ok;
+
+		return true;
+		}
+
+	return false;
+	}
+
+
+	template<class ValueType>
+	bool RootCheckIndexTwo(ValueType & x, const ValueType & index, ErrorCode * err)
+	{
+		if( index == 2 )
+		{
+			x = Sqrt(x, err);
+
+		return true;
+		}
+
+	return false;
+	}
+
+
+	template<class ValueType>
+	bool RootCheckIndexFrac(ValueType & x, const ValueType & index, ErrorCode * err)
+	{
+		if( !index.IsInteger() )
+		{
+			// index must be integer
+			if( err )
+				*err = err_improper_argument;
+
+			x.SetNan();
+
+		return true;
+		}
+
+	return false;
+	}
+
+
+	template<class ValueType>
+	bool RootCheckXZero(ValueType & x, ErrorCode * err)
+	{
+		if( x.IsZero() )
+		{
+			// root(0;index) is zero (if index!=0)
+			// RootCheckIndexZero() must be called beforehand
+			x.SetZero();
+
+			if( err )
+				*err = err_ok;
+
+		return true;
+		}
+
+	return false;
+	}
+
+
+	template<class ValueType>
+	bool RootCheckIndex(ValueType & x, const ValueType & index, ErrorCode * err, bool * change_sign)
+	{
+		*change_sign = false;
+
+		if( index.Mod2() )
+		{
+			// index is odd (1,3,5...)
+			if( x.IsSign() )
+			{
+				*change_sign = true;
+				x.Abs();
+			}
+		}
+		else
+		{
+			// index is even
+			// x cannot be negative
+			if( x.IsSign() )
+			{
+				if( err )
+					*err = err_improper_argument;
+
+				x.SetNan();
+
+				return true;
+			}
+		}
+
+	return false;
+	}
+
+
+	template<class ValueType>
+	uint RootCorrectInteger(ValueType & old_x, ValueType & x, const ValueType & index)
+	{
+		if( !old_x.IsInteger() || x.IsInteger() || !index.exponent.IsSign() )
+			return 0;
+
+		// old_x is integer,
+		// x is not integer,
+		// index is relatively small (index.exponent<0 or index.exponent<=0)
+		// (because we're using a special powering algorithm Big::PowUInt())
+
+		uint c = 0;
+
+		ValueType temp(x);
+		c += temp.Round();
+
+		ValueType temp_round(temp);
+		c += temp.PowUInt(index);
+
+		if( temp == old_x )
+			x = temp_round;
+
+	return (c==0)? 0 : 1;
+	}
+
+
+
+	} // namespace auxiliaryfunctions 
+
+
+
+	/*!
+		indexth Root of x
+		index must be integer and not negative <0;1;2;3....)
+
+		if index==0 the result is one
+		if x==0 the result is zero and we assume root(0;0) is not defined
+
+		if index is even (2;4;6...) the result is x^(1/index) and x>0
+		if index is odd (1;2;3;...) the result is either 
+			-(abs(x)^(1/index)) if x<0    or
+			       x^(1/index)) if x>0
+
+		(for index==1 the result is equal x)
+	*/
+	template<class ValueType>
+	ValueType Root(ValueType x, const ValueType & index, ErrorCode * err = 0)
+	{
+		using namespace auxiliaryfunctions;
+
+		if( x.IsNan() || index.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return ValueType(); // NaN is set by default
+		}
+
+		if( RootCheckIndexSign(x, index, err) ) return x;
+		if( RootCheckIndexZero(x, index, err) ) return x;
+		if( RootCheckIndexOne (   index, err) ) return x;
+		if( RootCheckIndexTwo (x, index, err) ) return x;
+		if( RootCheckIndexFrac(x, index, err) ) return x;
+		if( RootCheckXZero    (x,        err) ) return x;
+
+		// index integer and index!=0
+		// x!=0
+
+		ValueType old_x(x);
+		bool change_sign;
+
+		if( RootCheckIndex(x, index, err, &change_sign ) ) return x;
+
+		ValueType temp;
+		uint c = 0;
+
+		// we're using the formula: root(x ; n) = exp( ln(x) / n )
+		c += temp.Ln(x);
+		c += temp.Div(index);
+		c += x.Exp(temp);
+
+		if( change_sign )
+		{
+			// x is different from zero
+			x.SetSign();
+		}
+
+		c += RootCorrectInteger(old_x, x, index);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return x;
+	}
+
+
+
+	/*!
+		absolute value of x
+		e.g.  -2 = 2 
+		       2 = 2
+	*/
+	template<class ValueType>
+	ValueType Abs(const ValueType & x)
+	{
+		ValueType result( x );
+		result.Abs();
+
+	return result;
+	}
+
+
+	/*!
+		it returns the sign of the value
+		e.g.  -2 = -1 
+		       0 = 0
+		      10 = 1
+	*/
+	template<class ValueType>
+	ValueType Sgn(ValueType x)
+	{
+		x.Sgn();
+
+	return x;
+	}
+
+
+	/*!
+		the remainder from a division
+
+		e.g.
+		mod( 12.6 ;  3) =  0.6   because 12.6  = 3*4 + 0.6
+		mod(-12.6 ;  3) = -0.6   bacause -12.6 = 3*(-4) + (-0.6)
+		mod( 12.6 ; -3) =  0.6
+		mod(-12.6 ; -3) = -0.6
+	*/
+	template<class ValueType>
+	ValueType Mod(ValueType a, const ValueType & b, ErrorCode * err = 0)
+	{
+		if( a.IsNan() || b.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return ValueType(); // NaN is set by default
+		}
+
+		uint c = a.Mod(b);
+
+		if( err )
+			*err = c ? err_overflow : err_ok;
+
+	return a;
+	}
+
+
+
+	namespace auxiliaryfunctions
+	{
+
+	/*!
+		this function is used to store factorials in a given container
+		'more' means how many values should be added at the end
+
+			e.g.
+			std::vector<ValueType> fact;
+			SetFactorialSequence(fact, 3);
+			// now the container has three values: 1  1  2
+
+			SetFactorialSequence(fact, 2);
+			// now the container has five values:  1  1  2  6  24
+	*/
+	template<class ValueType>
+	void SetFactorialSequence(std::vector<ValueType> & fact, uint more = 20)
+	{
+		if( more == 0 )
+			more = 1;
+
+		uint start = static_cast<uint>(fact.size());
+		fact.resize(fact.size() + more);
+
+		if( start == 0 )
+		{
+			fact[0] = 1;
+			++start;
+		}
+
+		for(uint i=start ; i<fact.size() ; ++i)
+		{
+			fact[i] = fact[i-1];
+			fact[i].MulInt(i);
+		}
+	}
+
+
+	/*!
+		an auxiliary function used to calculate Bernoulli numbers
+
+		this function returns a sum:
+		sum(m) = sum_{k=0}^{m-1} {2^k * (m k) * B(k)}    k in [0, m-1]   (m k) means binomial coefficient = (m! / (k! * (m-k)!))
+
+		you should have sufficient factorials in cgamma.fact
+		(cgamma.fact should have at least m items)
+
+		n_ should be equal 2
+	*/
+	template<class ValueType>
+	ValueType SetBernoulliNumbersSum(CGamma<ValueType> & cgamma, const ValueType & n_, uint m,
+									  const volatile StopCalculating * stop = 0)
+	{
+	ValueType k_, temp, temp2, temp3, sum;
+
+		sum.SetZero();
+		
+		for(uint k=0 ; k<m ; ++k)			// k<m means k<=m-1
+		{
+			if( stop && (k & 15)==0 )		// means: k % 16 == 0
+				if( stop->WasStopSignal() )
+					return ValueType();		// NaN
+
+			if( k>1 && (k & 1) == 1 )		// for that k the Bernoulli number is zero
+				continue;
+
+			k_ = k;
+
+			temp = n_;				// n_ is equal 2
+			temp.Pow(k_);
+			// temp = 2^k
+
+			temp2 = cgamma.fact[m];
+			temp3 = cgamma.fact[k];
+			temp3.Mul(cgamma.fact[m-k]);
+			temp2.Div(temp3);
+			// temp2 = (m k) = m! / ( k! * (m-k)! )
+
+			temp.Mul(temp2);
+			temp.Mul(cgamma.bern[k]);
+
+			sum.Add(temp);
+			// sum += 2^k * (m k) * B(k)
+
+			if( sum.IsNan() )
+				break;
+		}
+
+	return sum;
+	}
+
+
+	/*!
+		an auxiliary function used to calculate Bernoulli numbers
+		start is >= 2
+
+		we use the recurrence formula: 
+		   B(m) = 1 / (2*(1 - 2^m)) * sum(m)
+		   where sum(m) is calculated by SetBernoulliNumbersSum()
+	*/
+	template<class ValueType>
+	bool SetBernoulliNumbersMore(CGamma<ValueType> & cgamma, uint start, const volatile StopCalculating * stop = 0)
+	{
+	ValueType denominator, temp, temp2, temp3, m_, sum, sum2, n_, k_;
+
+		const uint n = 2;
+		n_ = n;
+
+		// start is >= 2
+		for(uint m=start ; m<cgamma.bern.size() ; ++m)
+		{
+			if( (m & 1) == 1 )
+			{
+				cgamma.bern[m].SetZero();
+			}
+			else
+			{
+				m_ = m;
+
+				temp = n_;				// n_ = 2
+				temp.Pow(m_);
+				// temp = 2^m
+
+				denominator.SetOne();
+				denominator.Sub(temp);
+				if( denominator.exponent.AddOne() ) // it means: denominator.MulInt(2)
+					denominator.SetNan();
+
+				// denominator = 2 * (1 - 2^m)
+
+				cgamma.bern[m] = SetBernoulliNumbersSum(cgamma, n_, m, stop);
+
+				if( stop && stop->WasStopSignal() )
+				{
+					cgamma.bern.resize(m);		// valid numbers are in [0, m-1]
+					return false;
+				}
+
+				cgamma.bern[m].Div(denominator);
+			}
+		}
+
+	return true;
+	}
+
+
+	/*!
+		this function is used to calculate Bernoulli numbers,
+		returns false if there was a stop signal,
+		'more' means how many values should be added at the end
+
+			e.g.
+			typedef Big<1,2> MyBig;
+			CGamma<MyBig> cgamma;
+			SetBernoulliNumbers(cgamma, 3);
+			// now we have three first Bernoulli numbers:  1  -0.5  0.16667
+			
+			SetBernoulliNumbers(cgamma, 4);
+			// now we have 7 Bernoulli numbers:  1  -0.5  0.16667   0   -0.0333   0   0.0238
+	*/
+	template<class ValueType>
+	bool SetBernoulliNumbers(CGamma<ValueType> & cgamma, uint more = 20, const volatile StopCalculating * stop = 0)
+	{
+		if( more == 0 )
+			more = 1;
+
+		uint start = static_cast<uint>(cgamma.bern.size());
+		cgamma.bern.resize(cgamma.bern.size() + more);
+
+		if( start == 0 )
+		{
+			cgamma.bern[0].SetOne();
+			++start;
+		}
+
+		if( cgamma.bern.size() == 1 )
+			return true;
+
+		if( start == 1 )
+		{
+			cgamma.bern[1].Set05();
+			cgamma.bern[1].ChangeSign();
+			++start;
+		}
+
+		// we should have sufficient factorials in cgamma.fact
+		if( cgamma.fact.size() < cgamma.bern.size() )
+			SetFactorialSequence(cgamma.fact, static_cast<uint>(cgamma.bern.size() - cgamma.fact.size()));
+
+
+	return SetBernoulliNumbersMore(cgamma, start, stop);
+	}
+
+
+	/*!
+		an auxiliary function used to calculate the Gamma() function
+
+		we calculate a sum:
+		   sum(n) = sum_{m=2} { B(m) / ( (m^2 - m) * n^(m-1) )  } = 1/(12*n) - 1/(360*n^3) + 1/(1260*n^5) + ...
+	       B(m) means a mth Bernoulli number
+		   the sum starts from m=2, we calculate as long as the value will not change after adding a next part
+	*/
+	template<class ValueType>
+	ValueType GammaFactorialHighSum(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
+									const volatile StopCalculating * stop)
+	{
+	ValueType temp, temp2, denominator, sum, oldsum;
+
+		sum.SetZero();
+
+		for(uint m=2 ; m<TTMATH_ARITHMETIC_MAX_LOOP ; m+=2)
+		{
+			if( stop && (m & 3)==0 ) // (m & 3)==0 means: (m % 4)==0
+				if( stop->WasStopSignal() )
+				{
+					err = err_interrupt;
+					return ValueType(); // NaN
+				}
+
+			temp = (m-1);
+			denominator = n;
+			denominator.Pow(temp);
+			// denominator = n ^ (m-1)
+
+			temp = m;
+			temp2 = temp;
+			temp.Mul(temp2);
+			temp.Sub(temp2);
+			// temp = m^2 - m
+
+			denominator.Mul(temp);
+			// denominator = (m^2 - m) * n ^ (m-1)
+
+			if( m >= cgamma.bern.size() )
+			{
+				if( !SetBernoulliNumbers(cgamma, m - cgamma.bern.size() + 1 + 3, stop) ) // 3 more than needed
+				{
+					// there was the stop signal
+					err = err_interrupt;
+					return ValueType(); // NaN
+				}
+			}
+
+			temp = cgamma.bern[m];
+			temp.Div(denominator);
+
+			oldsum = sum;
+			sum.Add(temp);
+
+			if( sum.IsNan() || oldsum==sum )
+				break;
+		}
+
+	return sum;
+	}
+
+
+	/*!
+		an auxiliary function used to calculate the Gamma() function
+
+		we calculate a helper function GammaFactorialHigh() by using Stirling's series:
+		   n! = (n/e)^n * sqrt(2*pi*n) * exp( sum(n) )
+		   where n is a real number (not only an integer) and is sufficient large (greater than TTMATH_GAMMA_BOUNDARY)
+		   and sum(n) is calculated by GammaFactorialHighSum()
+	*/
+	template<class ValueType>
+	ValueType GammaFactorialHigh(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err,
+								 const volatile StopCalculating * stop)
+	{
+	ValueType temp, temp2, temp3, denominator, sum;
+
+		temp.Set2Pi();
+		temp.Mul(n);
+		temp2 = Sqrt(temp);
+		// temp2 = sqrt(2*pi*n)
+
+		temp = n;
+		temp3.SetE();
+		temp.Div(temp3);
+		temp.Pow(n);
+		// temp = (n/e)^n
+
+		sum = GammaFactorialHighSum(n, cgamma, err, stop);
+		temp3.Exp(sum);
+		// temp3 = exp(sum)
+
+		temp.Mul(temp2);
+		temp.Mul(temp3);
+
+	return temp;
+	}
+
+
+	/*!
+		an auxiliary function used to calculate the Gamma() function
+
+		Gamma(x) = GammaFactorialHigh(x-1)
+	*/
+	template<class ValueType>
+	ValueType GammaPlusHigh(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
+	{
+	ValueType one;
+
+		one.SetOne();
+		n.Sub(one);
+
+	return GammaFactorialHigh(n, cgamma, err, stop);
+	}
+
+
+	/*!
+		an auxiliary function used to calculate the Gamma() function
+	
+		we use this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
+		we use the formula:
+		   gamma(n) = (n-1)! = 1 * 2 * 3 * ... * (n-1) 
+	*/
+	template<class ValueType>
+	ValueType GammaPlusLowIntegerInt(uint n, CGamma<ValueType> & cgamma)
+	{
+		TTMATH_ASSERT( n > 0 )
+
+		if( n - 1 < static_cast<uint>(cgamma.fact.size()) )
+			return cgamma.fact[n - 1];
+
+		ValueType res;
+		uint start = 2;
+
+		if( cgamma.fact.size() < 2 )
+		{
+			res.SetOne();
+		}
+		else
+		{
+			start = static_cast<uint>(cgamma.fact.size());
+			res   = cgamma.fact[start-1];
+		}
+
+		for(uint i=start ; i<n ; ++i)
+			res.MulInt(i);
+
+	return res;
+	}
+	
+
+	/*!
+		an auxiliary function used to calculate the Gamma() function
+
+		we use this function when n is integer and a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
+	*/
+	template<class ValueType>
+	ValueType GammaPlusLowInteger(const ValueType & n, CGamma<ValueType> & cgamma)
+	{
+	sint n_;
+
+		n.ToInt(n_);
+
+	return GammaPlusLowIntegerInt(n_, cgamma);
+	}
+
+
+	/*!
+		an auxiliary function used to calculate the Gamma() function
+
+		we use this function when n is a small value (from 0 to TTMATH_GAMMA_BOUNDARY]
+		we use a recurrence formula:
+		   gamma(z+1) = z * gamma(z)
+		   then: gamma(z) = gamma(z+1) / z
+
+		   e.g.
+		   gamma(3.89) = gamma(2001.89) / ( 3.89 * 4.89 * 5.89 * ... * 1999.89 * 2000.89 )
+	*/
+	template<class ValueType>
+	ValueType GammaPlusLow(ValueType n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
+	{
+	ValueType one, denominator, temp, boundary;
+
+		if( n.IsInteger() )
+			return GammaPlusLowInteger(n, cgamma);
+
+		one.SetOne();
+		denominator = n;
+		boundary    = TTMATH_GAMMA_BOUNDARY;
+
+		while( n < boundary )
+		{
+			n.Add(one);
+			denominator.Mul(n);
+		}
+
+		n.Add(one);
+
+		// now n is sufficient big
+		temp = GammaPlusHigh(n, cgamma, err, stop);
+		temp.Div(denominator);
+
+	return temp;
+	}
+
+
+	/*!
+		an auxiliary function used to calculate the Gamma() function
+	*/
+	template<class ValueType>
+	ValueType GammaPlus(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
+	{
+		if( n > TTMATH_GAMMA_BOUNDARY )
+			return GammaPlusHigh(n, cgamma, err, stop);
+
+	return GammaPlusLow(n, cgamma, err, stop);
+	}
+
+
+	/*!
+		an auxiliary function used to calculate the Gamma() function
+
+		this function is used when n is negative
+		we use the reflection formula:
+		   gamma(1-z) * gamma(z) = pi / sin(pi*z)
+		   then: gamma(z) = pi / (sin(pi*z) * gamma(1-z))
+
+	*/
+	template<class ValueType>
+	ValueType GammaMinus(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode & err, const volatile StopCalculating * stop)
+	{
+	ValueType pi, denominator, temp, temp2;
+
+		if( n.IsInteger() )
+		{
+			// gamma function is not defined when n is negative and integer
+			err = err_improper_argument;
+			return temp; // NaN
+		}
+
+		pi.SetPi();
+
+		temp = pi;
+		temp.Mul(n);
+		temp2 = Sin(temp);
+		// temp2 = sin(pi * n)
+
+		temp.SetOne();
+		temp.Sub(n);
+		temp = GammaPlus(temp, cgamma, err, stop);
+		// temp = gamma(1 - n)
+
+		temp.Mul(temp2);
+		pi.Div(temp);
+
+	return pi;
+	}
+
+	} // namespace auxiliaryfunctions
+
+
+
+	/*!
+		this function calculates the Gamma function
+
+		it's multithread safe, you should create a CGamma<> object and use it whenever you call the Gamma()
+		e.g.
+			typedef Big<1,2> MyBig;
+			MyBig x=234, y=345.53;
+			CGamma<MyBig> cgamma;
+			std::cout << Gamma(x, cgamma) << std::endl;
+			std::cout << Gamma(y, cgamma) << std::endl;
+		in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
+		and they will be reused in next calls to the function
+
+		each thread should have its own CGamma<> object, and you can use these objects with Factorial() function too
+	*/
+	template<class ValueType>
+	ValueType Gamma(const ValueType & n, CGamma<ValueType> & cgamma, ErrorCode * err = 0,
+					const volatile StopCalculating * stop = 0)
+	{
+	using namespace auxiliaryfunctions;
+
+	ValueType result;
+	ErrorCode err_tmp;
+
+		if( n.IsNan() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN is set by default
+		}
+
+		if( cgamma.history.Get(n, result, err_tmp) )
+		{
+			if( err )
+				*err = err_tmp;
+
+			return result;
+		}
+
+		err_tmp = err_ok;
+
+		if( n.IsSign() )
+		{
+			result = GammaMinus(n, cgamma, err_tmp, stop);
+		}
+		else
+		if( n.IsZero() )
+		{
+			err_tmp = err_improper_argument;
+			result.SetNan();
+		}
+		else
+		{
+			result = GammaPlus(n, cgamma, err_tmp, stop);
+		}
+
+		if( result.IsNan() && err_tmp==err_ok )
+			err_tmp = err_overflow;
+
+		if( err )
+			*err = err_tmp;
+
+		if( stop && !stop->WasStopSignal() )
+			cgamma.history.Add(n, result, err_tmp);
+
+	return result;
+	}
+
+
+	/*!
+		this function calculates the Gamma function
+
+		note: this function should be used only in a single-thread environment
+	*/
+	template<class ValueType>
+	ValueType Gamma(const ValueType & n, ErrorCode * err = 0)
+	{
+	// warning: this static object is not thread safe
+	static CGamma<ValueType> cgamma;
+
+	return Gamma(n, cgamma, err);
+	}
+
+
+
+	namespace auxiliaryfunctions
+	{
+
+	/*!
+		an auxiliary function for calculating the factorial function
+
+		we use the formula:
+		   x! = gamma(x+1)
+	*/
+	template<class ValueType>
+	ValueType Factorial2(ValueType x,
+						 CGamma<ValueType> * cgamma = 0,
+						 ErrorCode * err = 0,
+						 const volatile StopCalculating * stop = 0)
+	{
+	ValueType result, one;
+
+		if( x.IsNan() || x.IsSign() || !x.IsInteger() )
+		{
+			if( err )
+				*err = err_improper_argument;
+
+		return result; // NaN set by default
+		}
+
+		one.SetOne();
+		x.Add(one);
+
+		if( cgamma )
+			return Gamma(x, *cgamma, err, stop);
+
+	return Gamma(x, err);
+	}
+	
+	} // namespace auxiliaryfunctions
+
+
+
+	/*!
+		the factorial from given 'x'
+		e.g.
+		Factorial(4) = 4! = 1*2*3*4
+
+		it's multithread safe, you should create a CGamma<> object and use it whenever you call the Factorial()
+		e.g.
+			typedef Big<1,2> MyBig;
+			MyBig x=234, y=54345;
+			CGamma<MyBig> cgamma;
+			std::cout << Factorial(x, cgamma) << std::endl;
+			std::cout << Factorial(y, cgamma) << std::endl;
+		in the CGamma<> object the function stores some coefficients (factorials, Bernoulli numbers),
+		and they will be reused in next calls to the function
+
+		each thread should have its own CGamma<> object, and you can use these objects with Gamma() function too
+	*/
+	template<class ValueType>
+	ValueType Factorial(const ValueType & x, CGamma<ValueType> & cgamma, ErrorCode * err = 0,
+						const volatile StopCalculating * stop = 0)
+	{
+		return auxiliaryfunctions::Factorial2(x, &cgamma, err, stop);
+	}
+
+
+	/*!
+		the factorial from given 'x'
+		e.g.
+		Factorial(4) = 4! = 1*2*3*4
+
+		note: this function should be used only in a single-thread environment
+	*/
+	template<class ValueType>
+	ValueType Factorial(const ValueType & x, ErrorCode * err = 0)
+	{
+		return auxiliaryfunctions::Factorial2(x, (CGamma<ValueType>*)0, err, 0);
+	}
+
+
+	/*!
+		this method prepares some coefficients: factorials and Bernoulli numbers
+		stored in 'fact' and 'bern' objects
+
+		we're defining the method here because we're using Gamma() function which
+		is not available in ttmathobjects.h
+
+		read the doc info in ttmathobjects.h file where CGamma<> struct is declared
+	*/
+	template<class ValueType>
+	void CGamma<ValueType>::InitAll()
+	{
+		ValueType x = TTMATH_GAMMA_BOUNDARY + 1;
+		
+		// history.Remove(x) removes only one object
+		// we must be sure that there are not others objects with the key 'x'
+		while( history.Remove(x) )
+		{
+		}
+
+		// the simplest way to initialize is to call the Gamma function with (TTMATH_GAMMA_BOUNDARY + 1)
+		// when x is larger then fewer coefficients we need
+		Gamma(x, *this);
+	}
+
+
+
+} // namespace
+
+
+/*!
+	this is for convenience for the user
+	he can only use '#include <ttmath/ttmath.h>' even if he uses the parser
+*/
+#include "ttmathparser.h"
+
+
+#ifdef _MSC_VER
+//warning C4127: conditional expression is constant
+#pragma warning( default: 4127 )
+//warning C4702: unreachable code
+#pragma warning( default: 4702 )
+//warning C4800: forcing value to bool 'true' or 'false' (performance warning)
+#pragma warning( default: 4800 )
+#endif
+
+#endif
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathbig.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathbig.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,5222 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/*
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef headerfilettmathbig
+#define headerfilettmathbig
+
+/*!
+    \file ttmathbig.h
+    \brief A Class for representing floating point numbers
+*/
+
+#include "ttmathint.h"
+#include "ttmaththreads.h"
+
+#include <iostream>
+
+#ifdef TTMATH_MULTITHREADS
+#include <signal.h>
+#endif
+
+namespace ttmath
+{
+
+
+/*!
+    \brief Big implements the floating point numbers
+*/
+template <uint exp, uint man>
+class Big
+{
+
+/*
+    value = mantissa * 2^exponent
+
+    exponent - an integer value with a sign
+    mantissa - an integer value without a sing
+
+    mantissa must be pushed into the left side that is the highest bit from
+    mantissa must be one (of course if there's another value than zero) -- this job
+    (pushing bits into the left side) making Standardizing() method
+
+    for example:
+    if we want to store value one (1) into our Big object we must:
+        set mantissa to 1
+        set exponent to 0
+        set info to 0
+        and call method Standardizing()
+*/
+
+
+public:
+
+Int<exp>  exponent;
+UInt<man> mantissa;
+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_BIG_SIGN 128
+
+
+/*!
+    Not a number
+    if this bit is set that there is not a valid number
+*/
+#define TTMATH_BIG_NAN  64
+
+
+/*!
+    Zero
+    if this bit is set that there is value zero
+    mantissa should be zero and exponent should be zero too
+    (the Standardizing() method does this)
+*/
+#define TTMATH_BIG_ZERO  32
+
+
+    /*!
+        this method sets NaN if there was a carry (and returns 1 in such a case)
+
+        c can be 0, 1 or other value different from zero
+    */
+    uint CheckCarry(uint c)
+    {
+        if( c != 0 )
+        {
+            SetNan();
+            return 1;
+        }
+
+    return 0;
+    }
+
+public:
+
+
+    /*!
+        returning the string represents the currect type of the library
+        we have following types:
+          asm_vc_32   - with asm code designed for Microsoft Visual C++ (32 bits)
+          asm_gcc_32  - with asm code designed for GCC (32 bits)
+          asm_vc_64   - with asm for VC (64 bit)
+          asm_gcc_64  - with asm for GCC (64 bit)
+          no_asm_32   - pure C++ version (32 bit) - without any asm code
+          no_asm_64   - pure C++ version (64 bit) - without any asm code
+    */
+    static const char * LibTypeStr()
+    {
+        return UInt<man>::LibTypeStr();
+    }
+
+
+    /*!
+        returning the currect type of the library
+    */
+    static LibTypeCode LibType()
+    {
+        return UInt<man>::LibType();
+    }
+
+
+
+    /*!
+        this method moves all bits from mantissa into its left side
+        (suitably changes the exponent) or if the mantissa is zero
+        it sets the exponent to zero as well
+        (and clears the sign bit and sets the zero bit)
+
+        it can return a carry
+        the carry will be when we don't have enough space in the exponent
+
+        you don't have to use this method if you don't change the mantissa
+        and exponent directly
+    */
+    uint Standardizing()
+    {
+        if( mantissa.IsTheHighestBitSet() )
+        {
+            ClearInfoBit(TTMATH_BIG_ZERO);
+            return 0;
+        }
+
+        if( CorrectZero() )
+            return 0;
+
+        uint comp = mantissa.CompensationToLeft();
+
+    return exponent.Sub( comp );
+    }
+
+
+private:
+
+    /*!
+        if the mantissa is equal zero this method sets exponent to zero and
+        info without the sign
+
+        it returns true if there was the correction
+    */
+    bool CorrectZero()
+    {
+        if( mantissa.IsZero() )
+        {
+            SetInfoBit(TTMATH_BIG_ZERO);
+            ClearInfoBit(TTMATH_BIG_SIGN);
+            exponent.SetZero();
+
+            return true;
+        }
+        else
+        {
+            ClearInfoBit(TTMATH_BIG_ZERO);
+        }
+
+    return false;
+    }
+
+
+public:
+
+    /*!
+        this method clears a specific bit in the 'info' variable
+
+        bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
+    */
+    void ClearInfoBit(unsigned char bit)
+    {
+        info = info & (~bit);
+    }
+
+
+    /*!
+        this method sets a specific bit in the 'info' variable
+
+        bit is one of: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
+
+    */
+    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: TTMATH_BIG_SIGN, TTMATH_BIG_NAN etc.
+    */
+    bool IsInfoBit(unsigned char bit) const
+    {
+        return (info & bit) != 0;
+    }
+
+
+    /*!
+        this method sets zero
+    */
+    void SetZero()
+    {
+        info = TTMATH_BIG_ZERO;
+        exponent.SetZero();
+        mantissa.SetZero();
+
+        /*
+            we don't have to compensate zero
+        */
+    }
+
+
+    /*!
+        this method sets one
+    */
+    void SetOne()
+    {
+        FromUInt(1);
+    }
+
+
+    /*!
+        this method sets value 0.5
+    */
+    void Set05()
+    {
+        FromUInt(1);
+        exponent.SubOne();
+    }
+
+
+    /*!
+        this method sets NaN flag (Not a Number)
+        when this flag is set that means there is no a valid number
+    */
+    void SetNan()
+    {
+        SetInfoBit(TTMATH_BIG_NAN);
+    }
+
+
+private:
+
+    /*!
+        this method sets the mantissa of the value of pi
+    */
+    void SetMantissaPi()
+    {
+    // this is a static table which represents the value of Pi (mantissa of it)
+    // (first is the highest word)
+    // we must define this table as 'unsigned int' because
+    // both on 32bit and 64bit platforms this table is 32bit
+    static const unsigned int temp_table[] = {
+        0xc90fdaa2, 0x2168c234, 0xc4c6628b, 0x80dc1cd1, 0x29024e08, 0x8a67cc74, 0x020bbea6, 0x3b139b22,
+        0x514a0879, 0x8e3404dd, 0xef9519b3, 0xcd3a431b, 0x302b0a6d, 0xf25f1437, 0x4fe1356d, 0x6d51c245,
+        0xe485b576, 0x625e7ec6, 0xf44c42e9, 0xa637ed6b, 0x0bff5cb6, 0xf406b7ed, 0xee386bfb, 0x5a899fa5,
+        0xae9f2411, 0x7c4b1fe6, 0x49286651, 0xece45b3d, 0xc2007cb8, 0xa163bf05, 0x98da4836, 0x1c55d39a,
+        0x69163fa8, 0xfd24cf5f, 0x83655d23, 0xdca3ad96, 0x1c62f356, 0x208552bb, 0x9ed52907, 0x7096966d,
+        0x670c354e, 0x4abc9804, 0xf1746c08, 0xca18217c, 0x32905e46, 0x2e36ce3b, 0xe39e772c, 0x180e8603,
+        0x9b2783a2, 0xec07a28f, 0xb5c55df0, 0x6f4c52c9, 0xde2bcbf6, 0x95581718, 0x3995497c, 0xea956ae5,
+        0x15d22618, 0x98fa0510, 0x15728e5a, 0x8aaac42d, 0xad33170d, 0x04507a33, 0xa85521ab, 0xdf1cba64,
+        0xecfb8504, 0x58dbef0a, 0x8aea7157, 0x5d060c7d, 0xb3970f85, 0xa6e1e4c7, 0xabf5ae8c, 0xdb0933d7,
+        0x1e8c94e0, 0x4a25619d, 0xcee3d226, 0x1ad2ee6b, 0xf12ffa06, 0xd98a0864, 0xd8760273, 0x3ec86a64,
+        0x521f2b18, 0x177b200c, 0xbbe11757, 0x7a615d6c, 0x770988c0, 0xbad946e2, 0x08e24fa0, 0x74e5ab31,
+        0x43db5bfc, 0xe0fd108e, 0x4b82d120, 0xa9210801, 0x1a723c12, 0xa787e6d7, 0x88719a10, 0xbdba5b26,
+        0x99c32718, 0x6af4e23c, 0x1a946834, 0xb6150bda, 0x2583e9ca, 0x2ad44ce8, 0xdbbbc2db, 0x04de8ef9,
+        0x2e8efc14, 0x1fbecaa6, 0x287c5947, 0x4e6bc05d, 0x99b2964f, 0xa090c3a2, 0x233ba186, 0x515be7ed,
+        0x1f612970, 0xcee2d7af, 0xb81bdd76, 0x2170481c, 0xd0069127, 0xd5b05aa9, 0x93b4ea98, 0x8d8fddc1,
+        0x86ffb7dc, 0x90a6c08f, 0x4df435c9, 0x34028492, 0x36c3fab4, 0xd27c7026, 0xc1d4dcb2, 0x602646de,
+        0xc9751e76, 0x3dba37bd, 0xf8ff9406, 0xad9e530e, 0xe5db382f, 0x413001ae, 0xb06a53ed, 0x9027d831,
+        0x179727b0, 0x865a8918, 0xda3edbeb, 0xcf9b14ed, 0x44ce6cba, 0xced4bb1b, 0xdb7f1447, 0xe6cc254b,
+        0x33205151, 0x2bd7af42, 0x6fb8f401, 0x378cd2bf, 0x5983ca01, 0xc64b92ec, 0xf032ea15, 0xd1721d03,
+        0xf482d7ce, 0x6e74fef6, 0xd55e702f, 0x46980c82, 0xb5a84031, 0x900b1c9e, 0x59e7c97f, 0xbec7e8f3,
+        0x23a97a7e, 0x36cc88be, 0x0f1d45b7, 0xff585ac5, 0x4bd407b2, 0x2b4154aa, 0xcc8f6d7e, 0xbf48e1d8,
+        0x14cc5ed2, 0x0f8037e0, 0xa79715ee, 0xf29be328, 0x06a1d58b, 0xb7c5da76, 0xf550aa3d, 0x8a1fbff0,
+        0xeb19ccb1, 0xa313d55c, 0xda56c9ec, 0x2ef29632, 0x387fe8d7, 0x6e3c0468, 0x043e8f66, 0x3f4860ee,
+        0x12bf2d5b, 0x0b7474d6, 0xe694f91e, 0x6dbe1159, 0x74a3926f, 0x12fee5e4, 0x38777cb6, 0xa932df8c,
+        0xd8bec4d0, 0x73b931ba, 0x3bc832b6, 0x8d9dd300, 0x741fa7bf, 0x8afc47ed, 0x2576f693, 0x6ba42466,
+        0x3aab639c, 0x5ae4f568, 0x3423b474, 0x2bf1c978, 0x238f16cb, 0xe39d652d, 0xe3fdb8be, 0xfc848ad9,
+        0x22222e04, 0xa4037c07, 0x13eb57a8, 0x1a23f0c7, 0x3473fc64, 0x6cea306b, 0x4bcbc886, 0x2f8385dd,
+        0xfa9d4b7f, 0xa2c087e8, 0x79683303, 0xed5bdd3a, 0x062b3cf5, 0xb3a278a6, 0x6d2a13f8, 0x3f44f82d,
+        0xdf310ee0, 0x74ab6a36, 0x4597e899, 0xa0255dc1, 0x64f31cc5, 0x0846851d, 0xf9ab4819, 0x5ded7ea1,
+        0xb1d510bd, 0x7ee74d73, 0xfaf36bc3, 0x1ecfa268, 0x359046f4, 0xeb879f92, 0x4009438b, 0x481c6cd7,
+        0x889a002e, 0xd5ee382b, 0xc9190da6, 0xfc026e47, 0x9558e447, 0x5677e9aa, 0x9e3050e2, 0x765694df,
+        0xc81f56e8, 0x80b96e71, 0x60c980dd, 0x98a573ea, 0x4472065a, 0x139cd290, 0x6cd1cb72, 0x9ec52a53 // last one was: 0x9ec52a52
+        //0x86d44014, ...
+        // (the last word 0x9ec52a52 was rounded up because the next one is 0x86d44014 -- first bit is one 0x8..)
+        // 256 32bit words for the mantissa -- about 2464 valid decimal digits
+        };
+        // the value of PI is comming from the website http://zenwerx.com/pi.php
+        // 3101 digits were taken from this website
+        //  (later the digits were compared with:
+        //   http://www.eveandersson.com/pi/digits/1000000 and http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html )
+        // and they were set into Big<1,400> type (using operator=(const char*) on a 32bit platform)
+        // and then the first 256 words were taken into this table
+        // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
+        // and on 64bit platform value 128 (256/2=128))
+
+        mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
+    }
+
+public:
+
+
+    /*!
+        this method sets the value of pi
+    */
+    void SetPi()
+    {
+        SetMantissaPi();
+        info = 0;
+        exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
+    }
+
+
+    /*!
+        this method sets the value of 0.5 * pi
+    */
+    void Set05Pi()
+    {
+        SetMantissaPi();
+        info = 0;
+        exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 1;
+    }
+
+
+    /*!
+        this method sets the value of 2 * pi
+    */
+    void Set2Pi()
+    {
+        SetMantissaPi();
+        info = 0;
+        exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 3;
+    }
+
+
+    /*!
+        this method sets the value of e
+        (the base of the natural logarithm)
+    */
+    void SetE()
+    {
+    static const unsigned int temp_table[] = {
+        0xadf85458, 0xa2bb4a9a, 0xafdc5620, 0x273d3cf1, 0xd8b9c583, 0xce2d3695, 0xa9e13641, 0x146433fb,
+        0xcc939dce, 0x249b3ef9, 0x7d2fe363, 0x630c75d8, 0xf681b202, 0xaec4617a, 0xd3df1ed5, 0xd5fd6561,
+        0x2433f51f, 0x5f066ed0, 0x85636555, 0x3ded1af3, 0xb557135e, 0x7f57c935, 0x984f0c70, 0xe0e68b77,
+        0xe2a689da, 0xf3efe872, 0x1df158a1, 0x36ade735, 0x30acca4f, 0x483a797a, 0xbc0ab182, 0xb324fb61,
+        0xd108a94b, 0xb2c8e3fb, 0xb96adab7, 0x60d7f468, 0x1d4f42a3, 0xde394df4, 0xae56ede7, 0x6372bb19,
+        0x0b07a7c8, 0xee0a6d70, 0x9e02fce1, 0xcdf7e2ec, 0xc03404cd, 0x28342f61, 0x9172fe9c, 0xe98583ff,
+        0x8e4f1232, 0xeef28183, 0xc3fe3b1b, 0x4c6fad73, 0x3bb5fcbc, 0x2ec22005, 0xc58ef183, 0x7d1683b2,
+        0xc6f34a26, 0xc1b2effa, 0x886b4238, 0x611fcfdc, 0xde355b3b, 0x6519035b, 0xbc34f4de, 0xf99c0238,
+        0x61b46fc9, 0xd6e6c907, 0x7ad91d26, 0x91f7f7ee, 0x598cb0fa, 0xc186d91c, 0xaefe1309, 0x85139270,
+        0xb4130c93, 0xbc437944, 0xf4fd4452, 0xe2d74dd3, 0x64f2e21e, 0x71f54bff, 0x5cae82ab, 0x9c9df69e,
+        0xe86d2bc5, 0x22363a0d, 0xabc52197, 0x9b0deada, 0x1dbf9a42, 0xd5c4484e, 0x0abcd06b, 0xfa53ddef,
+        0x3c1b20ee, 0x3fd59d7c, 0x25e41d2b, 0x669e1ef1, 0x6e6f52c3, 0x164df4fb, 0x7930e9e4, 0xe58857b6,
+        0xac7d5f42, 0xd69f6d18, 0x7763cf1d, 0x55034004, 0x87f55ba5, 0x7e31cc7a, 0x7135c886, 0xefb4318a,
+        0xed6a1e01, 0x2d9e6832, 0xa907600a, 0x918130c4, 0x6dc778f9, 0x71ad0038, 0x092999a3, 0x33cb8b7a,
+        0x1a1db93d, 0x7140003c, 0x2a4ecea9, 0xf98d0acc, 0x0a8291cd, 0xcec97dcf, 0x8ec9b55a, 0x7f88a46b,
+        0x4db5a851, 0xf44182e1, 0xc68a007e, 0x5e0dd902, 0x0bfd64b6, 0x45036c7a, 0x4e677d2c, 0x38532a3a,
+        0x23ba4442, 0xcaf53ea6, 0x3bb45432, 0x9b7624c8, 0x917bdd64, 0xb1c0fd4c, 0xb38e8c33, 0x4c701c3a,
+        0xcdad0657, 0xfccfec71, 0x9b1f5c3e, 0x4e46041f, 0x388147fb, 0x4cfdb477, 0xa52471f7, 0xa9a96910,
+        0xb855322e, 0xdb6340d8, 0xa00ef092, 0x350511e3, 0x0abec1ff, 0xf9e3a26e, 0x7fb29f8c, 0x183023c3,
+        0x587e38da, 0x0077d9b4, 0x763e4e4b, 0x94b2bbc1, 0x94c6651e, 0x77caf992, 0xeeaac023, 0x2a281bf6,
+        0xb3a739c1, 0x22611682, 0x0ae8db58, 0x47a67cbe, 0xf9c9091b, 0x462d538c, 0xd72b0374, 0x6ae77f5e,
+        0x62292c31, 0x1562a846, 0x505dc82d, 0xb854338a, 0xe49f5235, 0xc95b9117, 0x8ccf2dd5, 0xcacef403,
+        0xec9d1810, 0xc6272b04, 0x5b3b71f9, 0xdc6b80d6, 0x3fdd4a8e, 0x9adb1e69, 0x62a69526, 0xd43161c1,
+        0xa41d570d, 0x7938dad4, 0xa40e329c, 0xcff46aaa, 0x36ad004c, 0xf600c838, 0x1e425a31, 0xd951ae64,
+        0xfdb23fce, 0xc9509d43, 0x687feb69, 0xedd1cc5e, 0x0b8cc3bd, 0xf64b10ef, 0x86b63142, 0xa3ab8829,
+        0x555b2f74, 0x7c932665, 0xcb2c0f1c, 0xc01bd702, 0x29388839, 0xd2af05e4, 0x54504ac7, 0x8b758282,
+        0x2846c0ba, 0x35c35f5c, 0x59160cc0, 0x46fd8251, 0x541fc68c, 0x9c86b022, 0xbb709987, 0x6a460e74,
+        0x51a8a931, 0x09703fee, 0x1c217e6c, 0x3826e52c, 0x51aa691e, 0x0e423cfc, 0x99e9e316, 0x50c1217b,
+        0x624816cd, 0xad9a95f9, 0xd5b80194, 0x88d9c0a0, 0xa1fe3075, 0xa577e231, 0x83f81d4a, 0x3f2fa457,
+        0x1efc8ce0, 0xba8a4fe8, 0xb6855dfe, 0x72b0a66e, 0xded2fbab, 0xfbe58a30, 0xfafabe1c, 0x5d71a87e,
+        0x2f741ef8, 0xc1fe86fe, 0xa6bbfde5, 0x30677f0d, 0x97d11d49, 0xf7a8443d, 0x0822e506, 0xa9f4614e,
+        0x011e2a94, 0x838ff88c, 0xd68c8bb7, 0xc51eef6d, 0x49ea8ab4, 0xf2c3df5b, 0xb4e0735a, 0xb0d68749
+        // 0x2fe26dd4, ...
+        // 256 32bit words for the mantissa -- about 2464 valid decimal digits
+        };
+
+        // above value was calculated using Big<1,400> type on a 32bit platform
+        // and then the first 256 words were taken,
+        // the calculating was made by using ExpSurrounding0(1) method
+        // which took 1420 iterations
+        // (the result was compared with e taken from http://antwrp.gsfc.nasa.gov/htmltest/gifcity/e.2mil)
+        // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
+        // and on 64bit platform value 128 (256/2=128))
+
+        mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
+        exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
+        info = 0;
+    }
+
+
+    /*!
+        this method sets the value of ln(2)
+        the natural logarithm from 2
+    */
+    void SetLn2()
+    {
+    static const unsigned int temp_table[] = {
+        0xb17217f7, 0xd1cf79ab, 0xc9e3b398, 0x03f2f6af, 0x40f34326, 0x7298b62d, 0x8a0d175b, 0x8baafa2b,
+        0xe7b87620, 0x6debac98, 0x559552fb, 0x4afa1b10, 0xed2eae35, 0xc1382144, 0x27573b29, 0x1169b825,
+        0x3e96ca16, 0x224ae8c5, 0x1acbda11, 0x317c387e, 0xb9ea9bc3, 0xb136603b, 0x256fa0ec, 0x7657f74b,
+        0x72ce87b1, 0x9d6548ca, 0xf5dfa6bd, 0x38303248, 0x655fa187, 0x2f20e3a2, 0xda2d97c5, 0x0f3fd5c6,
+        0x07f4ca11, 0xfb5bfb90, 0x610d30f8, 0x8fe551a2, 0xee569d6d, 0xfc1efa15, 0x7d2e23de, 0x1400b396,
+        0x17460775, 0xdb8990e5, 0xc943e732, 0xb479cd33, 0xcccc4e65, 0x9393514c, 0x4c1a1e0b, 0xd1d6095d,
+        0x25669b33, 0x3564a337, 0x6a9c7f8a, 0x5e148e82, 0x074db601, 0x5cfe7aa3, 0x0c480a54, 0x17350d2c,
+        0x955d5179, 0xb1e17b9d, 0xae313cdb, 0x6c606cb1, 0x078f735d, 0x1b2db31b, 0x5f50b518, 0x5064c18b,
+        0x4d162db3, 0xb365853d, 0x7598a195, 0x1ae273ee, 0x5570b6c6, 0x8f969834, 0x96d4e6d3, 0x30af889b,
+        0x44a02554, 0x731cdc8e, 0xa17293d1, 0x228a4ef9, 0x8d6f5177, 0xfbcf0755, 0x268a5c1f, 0x9538b982,
+        0x61affd44, 0x6b1ca3cf, 0x5e9222b8, 0x8c66d3c5, 0x422183ed, 0xc9942109, 0x0bbb16fa, 0xf3d949f2,
+        0x36e02b20, 0xcee886b9, 0x05c128d5, 0x3d0bd2f9, 0x62136319, 0x6af50302, 0x0060e499, 0x08391a0c,
+        0x57339ba2, 0xbeba7d05, 0x2ac5b61c, 0xc4e9207c, 0xef2f0ce2, 0xd7373958, 0xd7622658, 0x901e646a,
+        0x95184460, 0xdc4e7487, 0x156e0c29, 0x2413d5e3, 0x61c1696d, 0xd24aaebd, 0x473826fd, 0xa0c238b9,
+        0x0ab111bb, 0xbd67c724, 0x972cd18b, 0xfbbd9d42, 0x6c472096, 0xe76115c0, 0x5f6f7ceb, 0xac9f45ae,
+        0xcecb72f1, 0x9c38339d, 0x8f682625, 0x0dea891e, 0xf07afff3, 0xa892374e, 0x175eb4af, 0xc8daadd8,
+        0x85db6ab0, 0x3a49bd0d, 0xc0b1b31d, 0x8a0e23fa, 0xc5e5767d, 0xf95884e0, 0x6425a415, 0x26fac51c,
+        0x3ea8449f, 0xe8f70edd, 0x062b1a63, 0xa6c4c60c, 0x52ab3316, 0x1e238438, 0x897a39ce, 0x78b63c9f,
+        0x364f5b8a, 0xef22ec2f, 0xee6e0850, 0xeca42d06, 0xfb0c75df, 0x5497e00c, 0x554b03d7, 0xd2874a00,
+        0x0ca8f58d, 0x94f0341c, 0xbe2ec921, 0x56c9f949, 0xdb4a9316, 0xf281501e, 0x53daec3f, 0x64f1b783,
+        0x154c6032, 0x0e2ff793, 0x33ce3573, 0xfacc5fdc, 0xf1178590, 0x3155bbd9, 0x0f023b22, 0x0224fcd8,
+        0x471bf4f4, 0x45f0a88a, 0x14f0cd97, 0x6ea354bb, 0x20cdb5cc, 0xb3db2392, 0x88d58655, 0x4e2a0e8a,
+        0x6fe51a8c, 0xfaa72ef2, 0xad8a43dc, 0x4212b210, 0xb779dfe4, 0x9d7307cc, 0x846532e4, 0xb9694eda,
+        0xd162af05, 0x3b1751f3, 0xa3d091f6, 0x56658154, 0x12b5e8c2, 0x02461069, 0xac14b958, 0x784934b8,
+        0xd6cce1da, 0xa5053701, 0x1aa4fb42, 0xb9a3def4, 0x1bda1f85, 0xef6fdbf2, 0xf2d89d2a, 0x4b183527,
+        0x8fd94057, 0x89f45681, 0x2b552879, 0xa6168695, 0xc12963b0, 0xff01eaab, 0x73e5b5c1, 0x585318e7,
+        0x624f14a5, 0x1a4a026b, 0x68082920, 0x57fd99b6, 0x6dc085a9, 0x8ac8d8ca, 0xf9eeeea9, 0x8a2400ca,
+        0xc95f260f, 0xd10036f9, 0xf91096ac, 0x3195220a, 0x1a356b2a, 0x73b7eaad, 0xaf6d6058, 0x71ef7afb,
+        0x80bc4234, 0x33562e94, 0xb12dfab4, 0x14451579, 0xdf59eae0, 0x51707062, 0x4012a829, 0x62c59cab,
+        0x347f8304, 0xd889659e, 0x5a9139db, 0x14efcc30, 0x852be3e8, 0xfc99f14d, 0x1d822dd6, 0xe2f76797,
+        0xe30219c8, 0xaa9ce884, 0x8a886eb3, 0xc87b7295, 0x988012e8, 0x314186ed, 0xbaf86856, 0xccd3c3b6,
+        0xee94e62f, 0x110a6783, 0xd2aae89c, 0xcc3b76fc, 0x435a0ce1, 0x34c2838f, 0xd571ec6c, 0x1366a993 // last one was: 0x1366a992
+        //0xcbb9ac40, ...
+        // (the last word 0x1366a992 was rounded up because the next one is 0xcbb9ac40 -- first bit is one 0xc..)
+        // 256 32bit words for the mantissa -- about 2464 valid decimal digits
+        };
+
+        // above value was calculated using Big<1,400> type on a 32bit platform
+        // and then the first 256 words were taken,
+        // the calculating was made by using LnSurrounding1(2) method
+        // which took 4035 iterations
+        // (the result was compared with ln(2) taken from http://ja0hxv.calico.jp/pai/estart.html)
+        // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
+        // and on 64bit platform value 128 (256/2=128))
+
+        mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
+        exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT);
+        info = 0;
+    }
+
+
+    /*!
+        this method sets the value of ln(10)
+        the natural logarithm from 10
+
+        I introduced this constant especially to make the conversion ToString()
+        being faster. In fact the method ToString() is keeping values of logarithms
+        it has calculated but it must calculate the logarithm at least once.
+        If a program, which uses this library, is running for a long time this
+        would be ok, but for programs which are running shorter, for example for
+        CGI applications which only once are printing values, this would be much
+        inconvenience. Then if we're printing with base (radix) 10 and the mantissa
+        of our value is smaller than or equal to TTMATH_BUILTIN_VARIABLES_SIZE
+        we don't calculate the logarithm but take it from this constant.
+    */
+    void SetLn10()
+    {
+    static const unsigned int temp_table[] = {
+        0x935d8ddd, 0xaaa8ac16, 0xea56d62b, 0x82d30a28, 0xe28fecf9, 0xda5df90e, 0x83c61e82, 0x01f02d72,
+        0x962f02d7, 0xb1a8105c, 0xcc70cbc0, 0x2c5f0d68, 0x2c622418, 0x410be2da, 0xfb8f7884, 0x02e516d6,
+        0x782cf8a2, 0x8a8c911e, 0x765aa6c3, 0xb0d831fb, 0xef66ceb0, 0x4ab3c6fa, 0x5161bb49, 0xd219c7bb,
+        0xca67b35b, 0x23605085, 0x8e93368d, 0x44789c4f, 0x5b08b057, 0xd5ede20f, 0x469ea58e, 0x9305e981,
+        0xe2478fca, 0xad3aee98, 0x9cd5b42e, 0x6a271619, 0xa47ecb26, 0x978c5d4f, 0xdb1d28ea, 0x57d4fdc0,
+        0xe40bf3cc, 0x1e14126a, 0x45765cde, 0x268339db, 0xf47fa96d, 0xeb271060, 0xaf88486e, 0xa9b7401e,
+        0x3dfd3c51, 0x748e6d6e, 0x3848c8d2, 0x5faf1bca, 0xe88047f1, 0x7b0d9b50, 0xa949eaaa, 0xdf69e8a5,
+        0xf77e3760, 0x4e943960, 0xe38a5700, 0xffde2db1, 0xad6bfbff, 0xd821ba0a, 0x4cb0466d, 0x61ba648e,
+        0xef99c8e5, 0xf6974f36, 0x3982a78c, 0xa45ddfc8, 0x09426178, 0x19127a6e, 0x3b70fcda, 0x2d732d47,
+        0xb5e4b1c8, 0xc0e5a10a, 0xaa6604a5, 0x324ec3dc, 0xbc64ea80, 0x6e198566, 0x1f1d366c, 0x20663834,
+        0x4d5e843f, 0x20642b97, 0x0a62d18e, 0x478f7bd5, 0x8fcd0832, 0x4a7b32a6, 0xdef85a05, 0xeb56323a,
+        0x421ef5e0, 0xb00410a0, 0xa0d9c260, 0x794a976f, 0xf6ff363d, 0xb00b6b33, 0xf42c58de, 0xf8a3c52d,
+        0xed69b13d, 0xc1a03730, 0xb6524dc1, 0x8c167e86, 0x99d6d20e, 0xa2defd2b, 0xd006f8b4, 0xbe145a2a,
+        0xdf3ccbb3, 0x189da49d, 0xbc1261c8, 0xb3e4daad, 0x6a36cecc, 0xb2d5ae5b, 0x89bf752f, 0xb5dfb353,
+        0xff3065c4, 0x0cfceec8, 0x1be5a9a9, 0x67fddc57, 0xc4b83301, 0x006bf062, 0x4b40ed7a, 0x56c6cdcd,
+        0xa2d6fe91, 0x388e9e3e, 0x48a93f5f, 0x5e3b6eb4, 0xb81c4a5b, 0x53d49ea6, 0x8e668aea, 0xba83c7f8,
+        0xfb5f06c3, 0x58ac8f70, 0xfa9d8c59, 0x8c574502, 0xbaf54c96, 0xc84911f0, 0x0482d095, 0x1a0af022,
+        0xabbab080, 0xec97efd3, 0x671e4e0e, 0x52f166b6, 0xcd5cd226, 0x0dc67795, 0x2e1e34a3, 0xf799677f,
+        0x2c1d48f1, 0x2944b6c5, 0x2ba1307e, 0x704d67f9, 0x1c1035e4, 0x4e927c63, 0x03cf12bf, 0xe2cd2e31,
+        0xf8ee4843, 0x344d51b0, 0xf37da42b, 0x9f0b0fd9, 0x134fb2d9, 0xf815e490, 0xd966283f, 0x23962766,
+        0xeceab1e4, 0xf3b5fc86, 0x468127e2, 0xb606d10d, 0x3a45f4b6, 0xb776102d, 0x2fdbb420, 0x80c8fa84,
+        0xd0ff9f45, 0xc58aef38, 0xdb2410fd, 0x1f1cebad, 0x733b2281, 0x52ca5f36, 0xddf29daa, 0x544334b8,
+        0xdeeaf659, 0x4e462713, 0x1ed485b4, 0x6a0822e1, 0x28db471c, 0xa53938a8, 0x44c3bef7, 0xf35215c8,
+        0xb382bc4e, 0x3e4c6f15, 0x6285f54c, 0x17ab408e, 0xccbf7f5e, 0xd16ab3f6, 0xced2846d, 0xf457e14f,
+        0xbb45d9c5, 0x646ad497, 0xac697494, 0x145de32e, 0x93907128, 0xd263d521, 0x79efb424, 0xd64651d6,
+        0xebc0c9f0, 0xbb583a44, 0xc6412c84, 0x85bb29a6, 0x4d31a2cd, 0x92954469, 0xa32b1abd, 0xf7f5202c,
+        0xa4aa6c93, 0x2e9b53cf, 0x385ab136, 0x2741f356, 0x5de9c065, 0x6009901c, 0x88abbdd8, 0x74efcf73,
+        0x3f761ad4, 0x35f3c083, 0xfd6b8ee0, 0x0bef11c7, 0xc552a89d, 0x58ce4a21, 0xd71e54f2, 0x4157f6c7,
+        0xd4622316, 0xe98956d7, 0x450027de, 0xcbd398d8, 0x4b98b36a, 0x0724c25c, 0xdb237760, 0xe9324b68,
+        0x7523e506, 0x8edad933, 0x92197f00, 0xb853a326, 0xb330c444, 0x65129296, 0x34bc0670, 0xe177806d,
+        0xe338dac4, 0x5537492a, 0xe19add83, 0xcf45000f, 0x5b423bce, 0x6497d209, 0xe30e18a1, 0x3cbf0687,
+        0x67973103, 0xd9485366, 0x81506bba, 0x2e93a9a4, 0x7dd59d3f, 0xf17cd746, 0x8c2075be, 0x552a4348 // last one was: 0x552a4347
+        // 0xb4a638ef, ...
+        //(the last word 0x552a4347 was rounded up because the next one is 0xb4a638ef -- first bit is one 0xb..)
+        // 256 32bit words for the mantissa -- about 2464 valid digits (decimal)
+        };
+
+        // above value was calculated using Big<1,400> type on a 32bit platform
+        // and then the first 256 32bit words were taken,
+        // the calculating was made by using LnSurrounding1(10) method
+        // which took 22080 iterations
+        // (the result was compared with ln(10) taken from http://ja0hxv.calico.jp/pai/estart.html)
+        // (the formula used in LnSurrounding1(x) converges badly when
+        // the x is greater than one but in fact we can use it, only the
+        // number of iterations will be greater)
+        // (TTMATH_BUILTIN_VARIABLES_SIZE on 32bit platform should have the value 256,
+        // and on 64bit platform value 128 (256/2=128))
+
+        mantissa.SetFromTable(temp_table, sizeof(temp_table) / sizeof(int));
+        exponent = -sint(man)*sint(TTMATH_BITS_PER_UINT) + 2;
+        info = 0;
+    }
+
+
+    /*!
+        this method sets the maximum value which can be held in this type
+    */
+    void SetMax()
+    {
+        info = 0;
+        mantissa.SetMax();
+        exponent.SetMax();
+
+        // we don't have to use 'Standardizing()' because the last bit from
+        // the mantissa is set
+    }
+
+
+    /*!
+        this method sets the minimum value which can be held in this type
+    */
+    void SetMin()
+    {
+        info = 0;
+
+        mantissa.SetMax();
+        exponent.SetMax();
+        SetSign();
+
+        // we don't have to use 'Standardizing()' because the last bit from
+        // the mantissa is set
+    }
+
+
+    /*!
+        testing whether there is a value zero or not
+    */
+    bool IsZero() const
+    {
+        return IsInfoBit(TTMATH_BIG_ZERO);
+    }
+
+
+    /*!
+        this method returns true when there's the sign set
+        also we don't check the NaN flag
+    */
+    bool IsSign() const
+    {
+        return IsInfoBit(TTMATH_BIG_SIGN);
+    }
+
+
+    /*!
+        this method returns true when there is not a valid number
+    */
+    bool IsNan() const
+    {
+        return IsInfoBit(TTMATH_BIG_NAN);
+    }
+
+
+
+    /*!
+        this method clears the sign
+        (there'll be an absolute value)
+
+            e.g.
+            -1 -> 1
+            2  -> 2
+    */
+    void Abs()
+    {
+        ClearInfoBit(TTMATH_BIG_SIGN);
+    }
+
+
+    /*!
+        this method remains the 'sign' of the value
+        e.g.  -2 = -1
+               0 = 0
+              10 = 1
+    */
+    void Sgn()
+    {
+        // we have to check the NaN flag, because the next SetOne() method would clear it
+        if( IsNan() )
+            return;
+
+        if( IsSign() )
+        {
+            SetOne();
+            SetSign();
+        }
+        else
+        if( IsZero() )
+            SetZero();
+        else
+            SetOne();
+    }
+
+
+
+    /*!
+        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_BIG_SIGN);
+    }
+
+
+    /*!
+        this method changes the sign
+        when there is a value of zero then the sign is not changed
+
+            e.g.
+            -1 -> 1
+            2  -> -2
+    */
+    void ChangeSign()
+    {
+        // we don't have to check the NaN flag here
+
+        if( IsZero() )
+            return;
+
+        if( IsSign() )
+            ClearInfoBit(TTMATH_BIG_SIGN);
+        else
+            SetInfoBit(TTMATH_BIG_SIGN);
+    }
+
+
+
+private:
+
+    /*!
+        this method does the half-to-even rounding (banker's rounding)
+
+        if is_half is:
+          true  - that means the rest was equal the half (0.5 decimal)
+          false - that means the rest was greater than a half (greater than 0.5 decimal)
+
+        if the rest was less than a half then don't call this method
+        (the rounding should does nothing then)
+    */
+    uint RoundHalfToEven(bool is_half, bool rounding_up = true)
+    {
+    uint c = 0;
+
+        if( !is_half || mantissa.IsTheLowestBitSet() )
+        {
+            if( rounding_up )
+            {
+                if( mantissa.AddOne() )
+                {
+                    mantissa.Rcr(1, 1);
+                    c = exponent.AddOne();
+                }
+            }
+            else
+            {
+                #ifdef TTMATH_DEBUG
+                uint c_from_zero =
+                #endif
+                mantissa.SubOne();
+
+                // we're using rounding_up=false in Add() when the mantissas have different signs
+                // mantissa can be zero only when previous mantissa was equal to ss2.mantissa
+                // but in such a case 'last_bit_set' will not be set and consequently 'do_rounding' will be false
+                TTMATH_ASSERT( c_from_zero == 0 )
+            }
+        }
+
+    return c;
+    }
+
+
+
+
+
+    /*!
+    *
+    *   basic mathematic functions
+    *
+    */
+
+private:
+
+
+    /*!
+        an auxiliary method for adding
+    */
+    void AddCheckExponents( Big<exp, man> & ss2,
+                            Int<exp> & exp_offset,
+                            bool & last_bit_set,
+                            bool & rest_zero,
+                            bool & do_adding,
+                            bool & do_rounding)
+    {
+    Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
+
+        if( exp_offset == mantissa_size_in_bits )
+        {
+            last_bit_set = ss2.mantissa.IsTheHighestBitSet();
+            rest_zero    = ss2.mantissa.AreFirstBitsZero(man*TTMATH_BITS_PER_UINT - 1);
+            do_rounding  = true;    // we'are only rounding
+        }
+        else
+        if( exp_offset < mantissa_size_in_bits )
+        {
+            uint moved = exp_offset.ToInt(); // how many times we must move ss2.mantissa
+            rest_zero  = true;
+
+            if( moved > 0 )
+            {
+                last_bit_set = static_cast<bool>( ss2.mantissa.GetBit(moved-1) );
+
+                if( moved > 1 )
+                    rest_zero = ss2.mantissa.AreFirstBitsZero(moved - 1);
+
+                // (2) moving 'exp_offset' times
+                ss2.mantissa.Rcr(moved, 0);
+            }
+
+            do_adding    = true;
+            do_rounding  = true;
+        }
+
+        // if exp_offset is greater than mantissa_size_in_bits then we do nothing
+        // ss2 is too small for taking into consideration in the sum
+    }
+
+
+    /*!
+        an auxiliary method for adding
+    */
+    uint AddMantissas(  Big<exp, man> & ss2,
+                        bool & last_bit_set,
+                        bool & rest_zero,
+                        bool & rounding_up)
+    {
+    uint c = 0;
+
+        if( IsSign() == ss2.IsSign() )
+        {
+            // values have the same signs
+            if( mantissa.Add(ss2.mantissa) )
+            {
+                // we have one bit more from addition (carry)
+                // now rest_zero means the old rest_zero with the old last_bit_set
+                rest_zero    = (!last_bit_set && rest_zero);
+                last_bit_set = mantissa.Rcr(1,1);
+                c += exponent.AddOne();
+            }
+
+            rounding_up = true;
+        }
+        else
+        {
+            // values have different signs
+            // there shouldn't be a carry here because
+            // (1) (2) guarantee that the mantissa of this
+            // is greater than or equal to the mantissa of the ss2
+
+            #ifdef TTMATH_DEBUG
+            uint c_temp =
+            #endif
+            mantissa.Sub(ss2.mantissa);
+
+            TTMATH_ASSERT( c_temp == 0 )
+        }
+
+    return c;
+    }
+
+
+public:
+
+
+    /*!
+        Addition this = this + ss2
+
+        it returns carry if the sum is too big
+    */
+    uint Add(Big<exp, man> ss2, bool round = true)
+    {
+    bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
+    Int<exp> exp_offset( exponent );
+    uint c = 0;
+
+        if( IsNan() || ss2.IsNan() )
+            return CheckCarry(1);
+
+        exp_offset.Sub( ss2.exponent );
+        exp_offset.Abs();
+
+        // (1) abs(this) will be >= abs(ss2)
+        if( SmallerWithoutSignThan(ss2) )
+        {
+            // !! use Swap here (not implemented yet)
+            Big<exp, man> temp(ss2);
+
+            ss2   = *this;
+            *this = temp;
+        }
+
+        if( ss2.IsZero() )
+            return 0;
+
+        last_bit_set = rest_zero = do_adding = do_rounding = rounding_up = false;
+        AddCheckExponents(ss2, exp_offset, last_bit_set, rest_zero, do_adding, do_rounding);
+
+        if( do_adding )
+            c += AddMantissas(ss2, last_bit_set, rest_zero, rounding_up);
+
+        if( !round || !last_bit_set )
+            do_rounding = false;
+
+        if( do_rounding )
+            c += RoundHalfToEven(rest_zero, rounding_up);
+
+        if( do_adding || do_rounding )
+            c += Standardizing();
+
+    return CheckCarry(c);
+    }
+
+
+
+    /*!
+        Subtraction this = this - ss2
+
+        it returns carry if the result is too big
+    */
+    uint Sub(Big<exp, man> ss2, bool round = true)
+    {
+        ss2.ChangeSign();
+
+    return Add(ss2, round);
+    }
+
+
+    /*!
+        bitwise AND
+
+        this and ss2 must be >= 0
+        return values:
+            0 - ok
+            1 - carry
+            2 - this or ss2 was negative
+    */
+    uint BitAnd(Big<exp, man> ss2)
+    {
+        if( IsNan() || ss2.IsNan() )
+            return CheckCarry(1);
+
+        if( IsSign() || ss2.IsSign() )
+            return 2;
+
+        if( IsZero() )
+            return 0;
+
+        if( ss2.IsZero() )
+        {
+            SetZero();
+            return 0;
+        }
+
+        Int<exp> exp_offset( exponent );
+        Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
+
+        uint c = 0;
+
+        exp_offset.Sub( ss2.exponent );
+        exp_offset.Abs();
+
+        // abs(this) will be >= abs(ss2)
+        if( SmallerWithoutSignThan(ss2) )
+        {
+            Big<exp, man> temp(ss2);
+
+            ss2   = *this;
+            *this = temp;
+        }
+
+        if( exp_offset >= mantissa_size_in_bits )
+        {
+            // the second value is too small
+            SetZero();
+            return 0;
+        }
+
+        // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
+        ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
+        mantissa.BitAnd(ss2.mantissa);
+
+        c += Standardizing();
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        bitwise OR
+
+        this and ss2 must be >= 0
+        return values:
+            0 - ok
+            1 - carry
+            2 - this or ss2 was negative
+    */
+    uint BitOr(Big<exp, man> ss2)
+    {
+        if( IsNan() || ss2.IsNan() )
+            return CheckCarry(1);
+
+        if( IsSign() || ss2.IsSign() )
+            return 2;
+
+        if( IsZero() )
+        {
+            *this = ss2;
+            return 0;
+        }
+
+        if( ss2.IsZero() )
+            return 0;
+
+        Int<exp> exp_offset( exponent );
+        Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
+
+        uint c = 0;
+
+        exp_offset.Sub( ss2.exponent );
+        exp_offset.Abs();
+
+        // abs(this) will be >= abs(ss2)
+        if( SmallerWithoutSignThan(ss2) )
+        {
+            Big<exp, man> temp(ss2);
+
+            ss2   = *this;
+            *this = temp;
+        }
+
+        if( exp_offset >= mantissa_size_in_bits )
+            // the second value is too small
+            return 0;
+
+        // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
+        ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
+        mantissa.BitOr(ss2.mantissa);
+
+        c += Standardizing();
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        bitwise XOR
+
+        this and ss2 must be >= 0
+        return values:
+            0 - ok
+            1 - carry
+            2 - this or ss2 was negative
+    */
+    uint BitXor(Big<exp, man> ss2)
+    {
+        if( IsNan() || ss2.IsNan() )
+            return CheckCarry(1);
+
+        if( IsSign() || ss2.IsSign() )
+            return 2;
+
+        if( ss2.IsZero() )
+            return 0;
+
+        if( IsZero() )
+        {
+            *this = ss2;
+            return 0;
+        }
+
+        Int<exp> exp_offset( exponent );
+        Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
+
+        uint c = 0;
+
+        exp_offset.Sub( ss2.exponent );
+        exp_offset.Abs();
+
+        // abs(this) will be >= abs(ss2)
+        if( SmallerWithoutSignThan(ss2) )
+        {
+            Big<exp, man> temp(ss2);
+
+            ss2   = *this;
+            *this = temp;
+        }
+
+        if( exp_offset >= mantissa_size_in_bits )
+            // the second value is too small
+            return 0;
+
+        // exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
+        ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
+        mantissa.BitXor(ss2.mantissa);
+
+        c += Standardizing();
+
+    return CheckCarry(c);
+    }
+
+
+
+    /*!
+        Multiplication this = this * ss2 (ss2 is uint)
+
+        ss2 without a sign
+    */
+    uint MulUInt(uint ss2)
+    {
+    UInt<man+1> man_result;
+    uint i,c = 0;
+
+        if( IsNan() )
+            return 1;
+
+        if( IsZero() )
+            return 0;
+
+        if( ss2 == 0 )
+        {
+            SetZero();
+            return 0;
+        }
+
+        // man_result = mantissa * ss2.mantissa
+        mantissa.MulInt(ss2, man_result);
+
+        sint bit = UInt<man>::FindLeadingBitInWord(man_result.table[man]); // man - last word
+
+        if( bit!=-1 && uint(bit) > (TTMATH_BITS_PER_UINT/2) )
+        {
+            // 'i' will be from 0 to TTMATH_BITS_PER_UINT
+            i = man_result.CompensationToLeft();
+            c = exponent.Add( TTMATH_BITS_PER_UINT - i );
+
+            for(i=0 ; i<man ; ++i)
+                mantissa.table[i] = man_result.table[i+1];
+        }
+        else
+        {
+            if( bit != -1 )
+            {
+                man_result.Rcr(bit+1, 0);
+                c += exponent.Add(bit+1);
+            }
+
+            for(i=0 ; i<man ; ++i)
+                mantissa.table[i] = man_result.table[i];
+        }
+
+        c += Standardizing();
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        Multiplication this = this * ss2 (ss2 is sint)
+
+        ss2 with a sign
+    */
+    uint MulInt(sint ss2)
+    {
+        if( IsNan() )
+            return 1;
+
+        if( ss2 == 0 )
+        {
+            SetZero();
+            return 0;
+        }
+
+        if( IsZero() )
+            return 0;
+
+        if( IsSign() == (ss2<0) )
+        {
+            // the signs are the same (both are either - or +), the result is positive
+            Abs();
+        }
+        else
+        {
+            // the signs are different, the result is negative
+            SetSign();
+        }
+
+        if( ss2<0 )
+            ss2 = -ss2;
+
+
+    return MulUInt( uint(ss2) );
+    }
+
+
+private:
+
+
+    /*!
+        this method checks whether a table pointed by 'tab' and 'len'
+        has the value 0.5 decimal
+        (it is treated as the comma operator would be before the highest bit)
+        call this method only if the highest bit is set - you have to test it beforehand
+
+        return:
+          true  - tab was equal the half (0.5 decimal)
+          false - tab was greater than a half (greater than 0.5 decimal)
+
+    */
+    bool CheckGreaterOrEqualHalf(uint * tab, uint len)
+    {
+    uint i;
+
+        TTMATH_ASSERT( len>0 && (tab[len-1] & TTMATH_UINT_HIGHEST_BIT)!=0 )
+
+        for(i=0 ; i<len-1 ; ++i)
+            if( tab[i] != 0 )
+                return false;
+
+        if( tab[i] != TTMATH_UINT_HIGHEST_BIT )
+            return false;
+
+    return true;
+    }
+
+
+
+public:
+
+
+    /*!
+        multiplication this = this * ss2
+        this method returns a carry
+    */
+    uint Mul(const Big<exp, man> & ss2, bool round = true)
+    {
+    TTMATH_REFERENCE_ASSERT( ss2 )
+
+    UInt<man*2> man_result;
+    uint c = 0;
+    uint i;
+
+        if( IsNan() || ss2.IsNan() )
+            return CheckCarry(1);
+
+        if( IsZero() )
+            return 0;
+
+        if( ss2.IsZero() )
+        {
+            SetZero();
+            return 0;
+        }
+
+        // man_result = mantissa * ss2.mantissa
+        mantissa.MulBig(ss2.mantissa, man_result);
+
+        // 'i' will be from 0 to man*TTMATH_BITS_PER_UINT
+        // because mantissa and ss2.mantissa are standardized
+        // (the highest bit in man_result is set to 1 or
+        // if there is a zero value in man_result the method CompensationToLeft()
+        // returns 0 but we'll correct this at the end in Standardizing() method)
+        i = man_result.CompensationToLeft();
+        uint exp_add = man * TTMATH_BITS_PER_UINT - i;
+
+        if( exp_add )
+            c += exponent.Add( exp_add );
+
+        c += exponent.Add( ss2.exponent );
+
+        for(i=0 ; i<man ; ++i)
+            mantissa.table[i] = man_result.table[i+man];
+
+        if( round && (man_result.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+        {
+            bool is_half = CheckGreaterOrEqualHalf(man_result.table, man);
+            c += RoundHalfToEven(is_half);
+        }
+
+        if( IsSign() == ss2.IsSign() )
+        {
+            // the signs are the same, the result is positive
+            Abs();
+        }
+        else
+        {
+            // the signs are different, the result is negative
+            // if the value is zero it will be corrected later in Standardizing method
+            SetSign();
+        }
+
+        c += Standardizing();
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        division this = this / ss2
+
+        return value:
+        0 - ok
+        1 - carry (in a division carry can be as well)
+        2 - improper argument (ss2 is zero)
+    */
+    uint Div(const Big<exp, man> & ss2, bool round = true)
+    {
+    TTMATH_REFERENCE_ASSERT( ss2 )
+
+    UInt<man*2> man1;
+    UInt<man*2> man2;
+    uint i,c = 0;
+
+        if( IsNan() || ss2.IsNan() )
+            return CheckCarry(1);
+
+        if( ss2.IsZero() )
+        {
+            SetNan();
+            return 2;
+        }
+
+        if( IsZero() )
+            return 0;
+
+        for(i=0 ; i<man ; ++i)
+        {
+            man1.table[i+man] = mantissa.table[i];
+            man2.table[i]     = ss2.mantissa.table[i];
+        }
+
+        for(i=0 ; i<man ; ++i)
+        {
+            man1.table[i] = 0;
+            man2.table[i+man] = 0;
+        }
+
+        man1.Div(man2);
+
+        i = man1.CompensationToLeft();
+
+        if( i )
+            c += exponent.Sub(i);
+
+        c += exponent.Sub(ss2.exponent);
+
+        for(i=0 ; i<man ; ++i)
+            mantissa.table[i] = man1.table[i+man];
+
+        if( round && (man1.table[man-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+        {
+            bool is_half = CheckGreaterOrEqualHalf(man1.table, man);
+            c += RoundHalfToEven(is_half);
+        }
+
+        if( IsSign() == ss2.IsSign() )
+            Abs();
+        else
+            SetSign(); // if there is a zero it will be corrected in Standardizing()
+
+        c += Standardizing();
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        the remainder from a division
+
+        e.g.
+         12.6 mod  3 =  0.6   because  12.6 = 3*4 + 0.6
+        -12.6 mod  3 = -0.6   bacause -12.6 = 3*(-4) + (-0.6)
+         12.6 mod -3 =  0.6
+        -12.6 mod -3 = -0.6
+
+        it means:
+        in other words: this(old) = ss2 * q + this(new)
+
+        return value:
+        0 - ok
+        1 - carry
+        2 - improper argument (ss2 is zero)
+    */
+    uint Mod(const Big<exp, man> & ss2)
+    {
+    TTMATH_REFERENCE_ASSERT( ss2 )
+
+    uint c = 0;
+
+        if( IsNan() || ss2.IsNan() )
+            return CheckCarry(1);
+
+        if( ss2.IsZero() )
+        {
+            SetNan();
+            return 2;
+        }
+
+        if( !SmallerWithoutSignThan(ss2) )
+        {
+            Big<exp, man> temp(*this);
+
+            c = temp.Div(ss2);
+            temp.SkipFraction();
+            c += temp.Mul(ss2);
+            c += Sub(temp);
+
+            if( !SmallerWithoutSignThan( ss2 ) )
+                c += 1;
+        }
+
+    return CheckCarry(c);
+    }
+
+
+
+
+    /*!
+        power this = this ^ pow
+        (pow without a sign)
+
+        binary algorithm (r-to-l)
+
+        return values:
+        0 - ok
+        1 - carry
+        2 - incorrect arguments (0^0)
+    */
+    template<uint pow_size>
+    uint Pow(UInt<pow_size> pow)
+    {
+        if( IsNan() )
+            return 1;
+
+        if( IsZero() )
+        {
+            if( pow.IsZero() )
+            {
+                // we don't define zero^zero
+                SetNan();
+                return 2;
+            }
+
+            // 0^(+something) is zero
+            return 0;
+        }
+
+        Big<exp, man> start(*this), start_temp;
+        Big<exp, man> result;
+        result.SetOne();
+        uint c = 0;
+
+        while( !c )
+        {
+            if( pow.table[0] & 1 )
+                c += result.Mul(start);
+
+            pow.Rcr(1);
+
+            if( pow.IsZero() )
+                break;
+
+            start_temp = start;
+            c += start.Mul(start_temp);
+        }
+
+        *this = result;
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        power this = this ^ pow
+        p can be negative
+
+        return values:
+        0 - ok
+        1 - carry
+        2 - incorrect arguments 0^0 or 0^(-something)
+    */
+    template<uint pow_size>
+    uint Pow(Int<pow_size> pow)
+    {
+        if( IsNan() )
+            return 1;
+
+        if( !pow.IsSign() )
+            return Pow( UInt<pow_size>(pow) );
+
+        if( IsZero() )
+        {
+            // if 'p' is negative then
+            // 'this' must be different from zero
+            SetNan();
+            return 2;
+        }
+
+        uint c = pow.ChangeSign();
+
+        Big<exp, man> t(*this);
+        c += t.Pow( UInt<pow_size>(pow) ); // here can only be a carry (return:1)
+
+        SetOne();
+        c += Div(t);
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        this method returns: 'this' mod 2
+        (either zero or one)
+
+        this method is much faster than using Mod( object_with_value_two )
+    */
+    uint Mod2() const
+    {
+        if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) )
+            return 0;
+
+        sint exp_int = exponent.ToInt();
+        // 'exp_int' is negative (or zero), we set it as positive
+        exp_int = -exp_int;
+
+    return mantissa.GetBit(exp_int);
+    }
+
+
+
+    /*!
+        power this = this ^ abs([pow])
+        pow is treated as a value without a sign and without a fraction
+         if pow has a sign then the method pow.Abs() is used
+         if pow has a fraction the fraction is skipped (not used in calculation)
+
+        return values:
+        0 - ok
+        1 - carry
+        2 - incorrect arguments (0^0)
+    */
+    uint PowUInt(Big<exp, man> pow)
+    {
+        if( IsNan() || pow.IsNan() )
+            return CheckCarry(1);
+
+        if( IsZero() )
+        {
+            if( pow.IsZero() )
+            {
+                SetNan();
+                return 2;
+            }
+
+            // 0^(+something) is zero
+            return 0;
+        }
+
+        if( pow.IsSign() )
+            pow.Abs();
+
+        Big<exp, man> start(*this), start_temp;
+        Big<exp, man> result;
+        Big<exp, man> one;
+        Int<exp> e_one;
+        uint c = 0;
+
+        e_one.SetOne();
+        one.SetOne();
+        result = one;
+
+        while( !c )
+        {
+            if( pow.Mod2() )
+                c += result.Mul(start);
+
+            c += pow.exponent.Sub( e_one ); // !! may use SubOne() here?
+
+            if( pow < one )
+                break;
+
+            start_temp = start;
+            c += start.Mul(start_temp);
+        }
+
+        *this = result;
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        power this = this ^ [pow]
+        pow is treated as a value without a fraction
+        pow can be negative
+
+        return values:
+        0 - ok
+        1 - carry
+        2 - incorrect arguments 0^0 or 0^(-something)
+    */
+    uint PowInt(const Big<exp, man> & pow)
+    {
+        TTMATH_REFERENCE_ASSERT( pow )
+
+        if( IsNan() || pow.IsNan() )
+            return CheckCarry(1);
+
+        if( !pow.IsSign() )
+            return PowUInt(pow);
+
+        if( IsZero() )
+        {
+            // if 'pow' is negative then
+            // 'this' must be different from zero
+            SetNan();
+            return 2;
+        }
+
+        Big<exp, man> temp(*this);
+        uint c = temp.PowUInt(pow); // here can only be a carry (result:1)
+
+        SetOne();
+        c += Div(temp);
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        power this = this ^ pow
+        this must be greater than zero (this > 0)
+        pow can be negative and with fraction
+
+        return values:
+        0 - ok
+        1 - carry
+        2 - incorrect argument ('this' <= 0)
+    */
+    uint PowFrac(const Big<exp, man> & pow)
+    {
+        TTMATH_REFERENCE_ASSERT( pow )
+
+        if( IsNan() || pow.IsNan() )
+            return CheckCarry(1);
+
+        Big<exp, man> temp;
+        uint c = temp.Ln(*this);
+
+        if( c != 0 ) // can be 2 from Ln()
+        {
+            SetNan();
+            return c;
+        }
+
+        c += temp.Mul(pow);
+        c += Exp(temp);
+
+    return CheckCarry(c);
+    }
+
+
+
+    /*!
+        power this = this ^ pow
+        pow can be negative and with fraction
+
+        return values:
+        0 - ok
+        1 - carry
+        2 - incorrect argument ('this' or 'pow')
+    */
+    uint Pow(const Big<exp, man> & pow)
+    {
+        TTMATH_REFERENCE_ASSERT( pow )
+
+        if( IsNan() || pow.IsNan() )
+            return CheckCarry(1);
+
+        if( IsZero() )
+        {
+            // 0^pow will be 0 only for pow>0
+            if( pow.IsSign() || pow.IsZero() )
+            {
+                SetNan();
+                return 2;
+            }
+
+            SetZero();
+
+        return 0;
+        }
+
+        if( pow.exponent>-int(man*TTMATH_BITS_PER_UINT) && pow.exponent<=0 )
+        {
+            if( pow.IsInteger() )
+                return PowInt( pow );
+        }
+
+    return PowFrac(pow);
+    }
+
+
+    /*!
+        this function calculates the square root
+        e.g. let this=9 then this.Sqrt() gives 3
+
+        return: 0 - ok
+                1 - carry
+                2 - improper argument (this<0 or NaN)
+    */
+    uint Sqrt()
+    {
+        if( IsNan() || IsSign() )
+        {
+            SetNan();
+            return 2;
+        }
+
+        if( IsZero() )
+            return 0;
+
+        Big<exp, man> old(*this);
+        Big<exp, man> ln;
+        uint c = 0;
+
+        // we're using the formula: sqrt(x) = e ^ (ln(x) / 2)
+        c += ln.Ln(*this);
+        c += ln.exponent.SubOne(); // ln = ln / 2
+        c += Exp(ln);
+
+        // above formula doesn't give accurate results for some integers
+        // e.g. Sqrt(81) would not be 9 but a value very closed to 9
+        // we're rounding the result, calculating result*result and comparing
+        // with the old value, if they are equal then the result is an integer too
+
+        if( !c && old.IsInteger() && !IsInteger() )
+        {
+            Big<exp, man> temp(*this);
+            c += temp.Round();
+
+            Big<exp, man> temp2(temp);
+            c += temp.Mul(temp2);
+
+            if( temp == old )
+                *this = temp2;
+        }
+
+    return CheckCarry(c);
+    }
+
+
+private:
+
+#ifdef TTMATH_CONSTANTSGENERATOR
+public:
+#endif
+
+    /*!
+        Exponent this = exp(x) = e^x where x is in (-1,1)
+
+        we're using the formula exp(x) = 1 + (x)/(1!) + (x^2)/(2!) + (x^3)/(3!) + ...
+    */
+    void ExpSurrounding0(const Big<exp,man> & x, uint * steps = 0)
+    {
+        TTMATH_REFERENCE_ASSERT( x )
+
+        Big<exp,man> denominator, denominator_i;
+        Big<exp,man> one, old_value, next_part;
+        Big<exp,man> numerator = x;
+
+        SetOne();
+        one.SetOne();
+        denominator.SetOne();
+        denominator_i.SetOne();
+
+        uint i;
+        old_value = *this;
+
+        // we begin from 1 in order to not test at the beginning
+    #ifdef TTMATH_CONSTANTSGENERATOR
+        for(i=1 ; true ; ++i)
+    #else
+        for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+    #endif
+        {
+            bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
+
+            next_part = numerator;
+
+            if( next_part.Div( denominator ) )
+                // if there is a carry here we only break the loop
+                // however the result we return as good
+                // it means there are too many parts of the formula
+                break;
+
+            // there shouldn't be a carry here
+            Add( next_part );
+
+            if( testing )
+            {
+                if( old_value == *this )
+                    // we've added next few parts of the formula but the result
+                    // is still the same then we break the loop
+                    break;
+                else
+                    old_value = *this;
+            }
+
+            // we set the denominator and the numerator for a next part of the formula
+            if( denominator_i.Add(one) )
+                // if there is a carry here the result we return as good
+                break;
+
+            if( denominator.Mul(denominator_i) )
+                break;
+
+            if( numerator.Mul(x) )
+                break;
+        }
+
+        if( steps )
+            *steps = i;
+    }
+
+public:
+
+
+    /*!
+        Exponent this = exp(x) = e^x
+
+        we're using the fact that our value is stored in form of:
+            x = mantissa * 2^exponent
+        then
+            e^x = e^(mantissa* 2^exponent) or
+            e^x = (e^mantissa)^(2^exponent)
+
+        'Exp' returns a carry if we can't count the result ('x' is too big)
+    */
+    uint Exp(const Big<exp,man> & x)
+    {
+    uint c = 0;
+
+        if( x.IsNan() )
+            return CheckCarry(1);
+
+        if( x.IsZero() )
+        {
+            SetOne();
+        return 0;
+        }
+
+        // m will be the value of the mantissa in range (-1,1)
+        Big<exp,man> m(x);
+        m.exponent = -sint(man*TTMATH_BITS_PER_UINT);
+
+        // 'e_' will be the value of '2^exponent'
+        //   e_.mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;  and
+        //   e_.exponent.Add(1) mean:
+        //     e_.mantissa.table[0] = 1;
+        //     e_.Standardizing();
+        //     e_.exponent.Add(man*TTMATH_BITS_PER_UINT)
+        //     (we must add 'man*TTMATH_BITS_PER_UINT' because we've taken it from the mantissa)
+        Big<exp,man> e_(x);
+        e_.mantissa.SetZero();
+        e_.mantissa.table[man-1] = TTMATH_UINT_HIGHEST_BIT;
+        c += e_.exponent.Add(1);
+        e_.Abs();
+
+        /*
+            now we've got:
+            m - the value of the mantissa in range (-1,1)
+            e_ - 2^exponent
+
+            e_ can be as:
+            ...2^-2, 2^-1, 2^0, 2^1, 2^2 ...
+            ...1/4 , 1/2 , 1  , 2  , 4   ...
+
+            above one e_ is integer
+
+            if e_ is greater than 1 we calculate the exponent as:
+                e^(m * e_) = ExpSurrounding0(m) ^ e_
+            and if e_ is smaller or equal one we calculate the exponent in this way:
+                e^(m * e_) = ExpSurrounding0(m* e_)
+            because if e_ is smaller or equal 1 then the product of m*e_ is smaller or equal m
+        */
+
+        if( e_ <= 1 )
+        {
+            m.Mul(e_);
+            ExpSurrounding0(m);
+        }
+        else
+        {
+            ExpSurrounding0(m);
+            c += PowUInt(e_);
+        }
+
+    return CheckCarry(c);
+    }
+
+
+
+
+private:
+
+#ifdef TTMATH_CONSTANTSGENERATOR
+public:
+#endif
+
+    /*!
+        Natural logarithm this = ln(x) where x in range <1,2)
+
+        we're using the formula:
+        ln x = 2 * [ (x-1)/(x+1) + (1/3)((x-1)/(x+1))^3 + (1/5)((x-1)/(x+1))^5 + ... ]
+    */
+    void LnSurrounding1(const Big<exp,man> & x, uint * steps = 0)
+    {
+        Big<exp,man> old_value, next_part, denominator, one, two, x1(x), x2(x);
+
+        one.SetOne();
+
+        if( x == one )
+        {
+            // LnSurrounding1(1) is 0
+            SetZero();
+            return;
+        }
+
+        two = 2;
+
+        x1.Sub(one);
+        x2.Add(one);
+
+        x1.Div(x2);
+        x2 = x1;
+        x2.Mul(x1);
+
+        denominator.SetOne();
+        SetZero();
+
+        old_value = *this;
+        uint i;
+
+
+    #ifdef TTMATH_CONSTANTSGENERATOR
+        for(i=1 ; true ; ++i)
+    #else
+        // we begin from 1 in order to not test at the beginning
+        for(i=1 ; i<=TTMATH_ARITHMETIC_MAX_LOOP ; ++i)
+    #endif
+        {
+            bool testing = ((i & 3) == 0); // it means '(i % 4) == 0'
+
+            next_part = x1;
+
+            if( next_part.Div(denominator) )
+                // if there is a carry here we only break the loop
+                // however the result we return as good
+                // it means there are too many parts of the formula
+                break;
+
+            // there shouldn't be a carry here
+            Add(next_part);
+
+            if( testing )
+            {
+                if( old_value == *this )
+                    // we've added next (step_test) parts of the formula but the result
+                    // is still the same then we break the loop
+                    break;
+                else
+                    old_value = *this;
+            }
+
+            if( x1.Mul(x2) )
+                // if there is a carry here the result we return as good
+                break;
+
+            if( denominator.Add(two) )
+                break;
+        }
+
+        // this = this * 2
+        // ( there can't be a carry here because we calculate the logarithm between <1,2) )
+        exponent.AddOne();
+
+        if( steps )
+            *steps = i;
+    }
+
+
+
+
+public:
+
+
+    /*!
+        Natural logarithm this = ln(x)
+        (a logarithm with the base equal 'e')
+
+        we're using the fact that our value is stored in form of:
+            x = mantissa * 2^exponent
+        then
+            ln(x) = ln (mantissa * 2^exponent) = ln (mantissa) + (exponent * ln (2))
+
+        the mantissa we'll show as a value from range <1,2) because the logarithm
+        is decreasing too fast when 'x' is going to 0
+
+        return values:
+            0 - ok
+            1 - overflow (carry)
+            2 - incorrect argument (x<=0)
+    */
+    uint Ln(const Big<exp,man> & x)
+    {
+        TTMATH_REFERENCE_ASSERT( x )
+
+        if( x.IsNan() )
+            return CheckCarry(1);
+
+        if( x.IsSign() || x.IsZero() )
+        {
+            SetNan();
+            return 2;
+        }
+
+        // m will be the value of the mantissa in range <1,2)
+        Big<exp,man> m(x);
+        m.exponent = -sint(man*TTMATH_BITS_PER_UINT - 1);
+
+        LnSurrounding1(m);
+
+        Big<exp,man> exponent_temp;
+        exponent_temp.FromInt( x.exponent );
+
+        // we must add 'man*TTMATH_BITS_PER_UINT-1' because we've taken it from the mantissa
+        uint c = exponent_temp.Add(man*TTMATH_BITS_PER_UINT-1);
+
+        Big<exp,man> ln2;
+        ln2.SetLn2();
+        c += exponent_temp.Mul(ln2);
+        c += Add(exponent_temp);
+
+    return CheckCarry(c);
+    }
+
+
+
+    /*!
+        Logarithm from 'x' with a 'base'
+
+        we're using the formula:
+            Log(x) with 'base' = ln(x) / ln(base)
+
+        return values:
+            0 - ok
+            1 - overflow
+            2 - incorrect argument (x<=0)
+            3 - incorrect base (a<=0 lub a=1)
+    */
+    uint Log(const Big<exp,man> & x, const Big<exp,man> & base)
+    {
+        TTMATH_REFERENCE_ASSERT( base )
+        TTMATH_REFERENCE_ASSERT( x )
+
+        if( x.IsNan() || base.IsNan() )
+            return CheckCarry(1);
+
+        if( x.IsSign() || x.IsZero() )
+        {
+            SetNan();
+            return 2;
+        }
+
+        Big<exp,man> denominator;;
+        denominator.SetOne();
+
+        if( base.IsSign() || base.IsZero() || base==denominator )
+        {
+            SetNan();
+            return 3;
+        }
+
+        if( x == denominator ) // (this is: if x == 1)
+        {
+            // log(1) is 0
+            SetZero();
+            return 0;
+        }
+
+        // another error values we've tested at the beginning
+        // there can only be a carry
+        uint c = Ln(x);
+
+        c += denominator.Ln(base);
+        c += Div(denominator);
+
+    return CheckCarry(c);
+    }
+
+
+
+
+    /*!
+    *
+    *   converting methods
+    *
+    */
+
+
+    /*!
+        converting from another type of a Big object
+    */
+    template<uint another_exp, uint another_man>
+    uint FromBig(const Big<another_exp, another_man> & another)
+    {
+        info = another.info;
+
+        if( IsNan() )
+            return 1;
+
+        if( exponent.FromInt(another.exponent) )
+        {
+            SetNan();
+            return 1;
+        }
+
+        uint man_len_min = (man < another_man)? man : another_man;
+        uint i;
+        uint c = 0;
+
+        for( i = 0 ; i<man_len_min ; ++i )
+            mantissa.table[man-1-i] = another.mantissa.table[another_man-1-i];
+
+        for( ; i<man ; ++i )
+            mantissa.table[man-1-i] = 0;
+
+
+        // MS Visual Express 2005 reports a warning (in the lines with 'uint man_diff = ...'):
+        // warning C4307: '*' : integral constant overflow
+        // but we're using 'if( man > another_man )' and 'if( man < another_man )' and there'll be no such situation here
+        #ifdef _MSC_VER
+        #pragma warning( disable: 4307 )
+        #endif
+
+        if( man > another_man )
+        {
+            uint man_diff = (man - another_man) * TTMATH_BITS_PER_UINT;
+            c += exponent.SubInt(man_diff, 0);
+        }
+        else
+        if( man < another_man )
+        {
+            uint man_diff = (another_man - man) * TTMATH_BITS_PER_UINT;
+            c += exponent.AddInt(man_diff, 0);
+        }
+
+        #ifdef _MSC_VER
+        #pragma warning( default: 4307 )
+        #endif
+
+        // mantissa doesn't have to be standardized (either the highest bit is set or all bits are equal zero)
+        CorrectZero();
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        this method converts 'this' into 'result'
+
+        if the value is too big this method returns a carry (1)
+    */
+    uint ToUInt(uint & result, bool test_sign = true) const
+    {
+        result = 0;
+
+        if( IsZero() )
+            return 0;
+
+        if( test_sign && IsSign() )
+            // the result should be positive
+            return 1;
+
+        sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
+
+        if( exponent > maxbit + sint(TTMATH_BITS_PER_UINT) )
+            // if exponent > (maxbit + sint(TTMATH_BITS_PER_UINT)) the value can't be passed
+            // into the 'sint' type (it's too big)
+            return 1;
+
+        if( exponent <= maxbit )
+            // our value is from the range of (-1,1) and we return zero
+            return 0;
+
+        UInt<man> mantissa_temp(mantissa);
+        // exponent is from a range of (maxbit, maxbit + sint(TTMATH_BITS_PER_UINT) >
+        sint how_many_bits = exponent.ToInt();
+
+        // how_many_bits is negative, we'll make it positive
+        how_many_bits = -how_many_bits;
+
+        // we're taking into account only the last word in a mantissa table
+        mantissa_temp.Rcr( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
+        result = mantissa_temp.table[ man-1 ];
+
+    return 0;
+    }
+
+
+
+    /*!
+        this method converts 'this' into 'result'
+
+        if the value is too big this method returns a carry (1)
+    */
+    uint ToInt(sint & result) const
+    {
+        result = 0;
+        uint result_uint;
+
+        if( ToUInt(result_uint, false) )
+            return 1;
+
+        result = static_cast<sint>( result_uint );
+
+        // the exception for the minimal value
+        if( IsSign() && result_uint == TTMATH_UINT_HIGHEST_BIT )
+            return 0;
+
+        if( (result_uint & TTMATH_UINT_HIGHEST_BIT) != 0 )
+            // the value is too big
+            return 1;
+
+        if( IsSign() )
+            result = -result;
+
+    return 0;
+    }
+
+
+    /*!
+        this method converts 'this' into 'result'
+
+        if the value is too big this method returns a carry (1)
+    */
+    template<uint int_size>
+    uint ToInt(Int<int_size> & result) const
+    {
+        result.SetZero();
+
+        if( IsZero() )
+            return 0;
+
+        sint maxbit = -sint(man*TTMATH_BITS_PER_UINT);
+
+        if( exponent > maxbit + sint(int_size*TTMATH_BITS_PER_UINT) )
+            // if exponent > (maxbit + sint(int_size*TTMATH_BITS_PER_UINT)) the value can't be passed
+            // into the 'Int<int_size>' type (it's too big)
+            return 1;
+
+        if( exponent <= maxbit )
+            // our value is from range (-1,1) and we return zero
+            return 0;
+
+        sint how_many_bits = exponent.ToInt();
+
+        if( how_many_bits < 0 )
+        {
+            how_many_bits = -how_many_bits;
+            uint index    = how_many_bits / TTMATH_BITS_PER_UINT;
+
+            UInt<man> mantissa_temp(mantissa);
+            mantissa_temp.Rcr( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
+
+            for(uint i=index, a=0 ; i<man ; ++i,++a)
+                result.table[a] = mantissa_temp.table[i];
+        }
+        else
+        {
+            uint index = how_many_bits / TTMATH_BITS_PER_UINT;
+
+            for(uint i=0 ; i<man ; ++i)
+                result.table[index+i] = mantissa.table[i];
+
+            result.Rcl( how_many_bits % TTMATH_BITS_PER_UINT, 0 );
+        }
+
+        // the exception for the minimal value
+        if( IsSign() )
+        {
+            Int<int_size> min;
+            min.SetMin();
+
+            if( result == min )
+                return 0;
+        }
+
+        if( (result.table[int_size-1] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+            // the value is too big
+            return 1;
+
+        if( IsSign() )
+            result.ChangeSign();
+
+    return 0;
+    }
+
+
+    /*!
+        a method for converting 'uint' to this class
+    */
+    void FromUInt(uint value)
+    {
+        info = 0;
+
+        for(uint i=0 ; i<man-1 ; ++i)
+            mantissa.table[i] = 0;
+
+        mantissa.table[man-1] = value;
+        exponent = -sint(man-1) * sint(TTMATH_BITS_PER_UINT);
+
+        // there shouldn't be a carry because 'value' has the 'uint' type
+        Standardizing();
+    }
+
+
+    /*!
+        a method for converting 'sint' to this class
+    */
+    void FromInt(sint value)
+    {
+    bool is_sign = false;
+
+        if( value < 0 )
+        {
+            value   = -value;
+            is_sign = true;
+        }
+
+        FromUInt(uint(value));
+
+        if( is_sign )
+            SetSign();
+    }
+
+
+
+    /*!
+        this method converts from standard double into this class
+
+        standard double means IEEE-754 floating point value with 64 bits
+        it is as follows (from http://www.psc.edu/general/software/packages/ieee/ieee.html):
+
+        The IEEE double precision floating point standard representation requires
+        a 64 bit word, which may be represented as numbered from 0 to 63, left to
+        right. The first bit is the sign bit, S, the next eleven bits are the
+        exponent bits, 'E', and the final 52 bits are the fraction 'F':
+
+        S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+        0 1        11 12                                                63
+
+        The value V represented by the word may be determined as follows:
+
+        * If E=2047 and F is nonzero, then V=NaN ("Not a number")
+        * If E=2047 and F is zero and S is 1, then V=-Infinity
+        * If E=2047 and F is zero and S is 0, then V=Infinity
+        * If 0<E<2047 then V=(-1)**S * 2 ** (E-1023) * (1.F) where "1.F" is intended
+          to represent the binary number created by prefixing F with an implicit
+          leading 1 and a binary point.
+        * If E=0 and F is nonzero, then V=(-1)**S * 2 ** (-1022) * (0.F) These are
+          "unnormalized" values.
+        * If E=0 and F is zero and S is 1, then V=-0
+        * If E=0 and F is zero and S is 0, then V=0
+    */
+
+#ifdef TTMATH_PLATFORM32
+
+    void FromDouble(double value)
+    {
+        // sizeof(double) should be 8 (64 bits), this is actually not a runtime
+        // error but I leave it at the moment as is
+        TTMATH_ASSERT( sizeof(double) == 8 )
+
+        // I am not sure what will be on a platform which has
+        // a different endianness... but we use this library only
+        // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
+        union
+        {
+            double d;
+            uint u[2]; // two 32bit words
+        } temp;
+
+        temp.d = value;
+
+        sint e  = ( temp.u[1] & 0x7FF00000u) >> 20;
+        uint m1 = ((temp.u[1] &    0xFFFFFu) << 11) | (temp.u[0] >> 21);
+        uint m2 = temp.u[0] << 11;
+
+        if( e == 2047 )
+        {
+            // If E=2047 and F is nonzero, then V=NaN ("Not a number")
+            // If E=2047 and F is zero and S is 1, then V=-Infinity
+            // If E=2047 and F is zero and S is 0, then V=Infinity
+
+            // we do not support -Infinity and +Infinity
+            // we assume that there is always NaN
+
+            SetNan();
+        }
+        else
+        if( e > 0 )
+        {
+            // If 0<E<2047 then
+            // V=(-1)**S * 2 ** (E-1023) * (1.F)
+            // where "1.F" is intended to represent the binary number
+            // created by prefixing F with an implicit leading 1 and a binary point.
+
+            FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
+                                    e - 1023 - man*TTMATH_BITS_PER_UINT + 1, 0x80000000u,
+                                    m1, m2);
+
+            // we do not have to call Standardizing() here
+            // because the mantissa will have the highest bit set
+        }
+        else
+        {
+            // e == 0
+
+            if( m1 != 0 || m2 != 0 )
+            {
+                // If E=0 and F is nonzero,
+                // then V=(-1)**S * 2 ** (-1022) * (0.F)
+                // These are "unnormalized" values.
+
+                UInt<2> m;
+                m.table[1] = m1;
+                m.table[0] = m2;
+                uint moved = m.CompensationToLeft();
+
+                FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
+                                        e - 1022 - man*TTMATH_BITS_PER_UINT + 1 - moved, 0,
+                                        m.table[1], m.table[2]);
+            }
+            else
+            {
+                // If E=0 and F is zero and S is 1, then V=-0
+                // If E=0 and F is zero and S is 0, then V=0
+
+                // we do not support -0 or 0, only is one 0
+                SetZero();
+            }
+        }
+    }
+
+
+private:
+
+    void FromDouble_SetExpAndMan(bool is_sign, int e, uint mhighest, uint m1, uint m2)
+    {
+        exponent = e;
+
+        if( man > 1 )
+        {
+            mantissa.table[man-1] = m1 | mhighest;
+            mantissa.table[sint(man-2)] = m2;
+            // although man>1 we're using casting into sint
+            // to get rid from a warning which generates Microsoft Visual:
+            // warning C4307: '*' : integral constant overflow
+
+            for(uint i=0 ; i<man-2 ; ++i)
+                mantissa.table[i] = 0;
+        }
+        else
+        {
+            mantissa.table[0] = m1 | mhighest;
+        }
+
+        info = 0;
+
+        // the value should be different from zero
+        TTMATH_ASSERT( mantissa.IsZero() == false )
+
+        if( is_sign )
+            SetSign();
+    }
+
+
+#else
+
+public:
+
+    // 64bit platforms
+    void FromDouble(double value)
+    {
+        // sizeof(double) should be 8 (64 bits), this is actually not a runtime
+        // error but I leave it at the moment as is
+        TTMATH_ASSERT( sizeof(double) == 8 )
+
+        // I am not sure what will be on a plaltform which has
+        // a different endianness... but we use this library only
+        // on x86 and amd (intel) 64 bits (as there's a lot of assembler code)
+        union
+        {
+            double d;
+            uint u; // one 64bit word
+        } temp;
+
+        temp.d = value;
+
+        sint e = (temp.u & 0x7FF0000000000000ul) >> 52;
+        uint m = (temp.u &    0xFFFFFFFFFFFFFul) << 11;
+
+        if( e == 2047 )
+        {
+            // If E=2047 and F is nonzero, then V=NaN ("Not a number")
+            // If E=2047 and F is zero and S is 1, then V=-Infinity
+            // If E=2047 and F is zero and S is 0, then V=Infinity
+
+            // we do not support -Infinity and +Infinity
+            // we assume that there is always NaN
+
+            SetNan();
+        }
+        else
+        if( e > 0 )
+        {
+            // If 0<E<2047 then
+            // V=(-1)**S * 2 ** (E-1023) * (1.F)
+            // where "1.F" is intended to represent the binary number
+            // created by prefixing F with an implicit leading 1 and a binary point.
+
+            FromDouble_SetExpAndMan((temp.u & 0x8000000000000000ul) != 0,
+                                    e - 1023 - man*TTMATH_BITS_PER_UINT + 1,
+                                    0x8000000000000000ul, m);
+
+            // we do not have to call Standardizing() here
+            // because the mantissa will have the highest bit set
+        }
+        else
+        {
+            // e == 0
+
+            if( m != 0 )
+            {
+                // If E=0 and F is nonzero,
+                // then V=(-1)**S * 2 ** (-1022) * (0.F)
+                // These are "unnormalized" values.
+
+                FromDouble_SetExpAndMan(bool(temp.u & 0x8000000000000000ul),
+                                        e - 1022 - man*TTMATH_BITS_PER_UINT + 1, 0, m);
+                Standardizing();
+            }
+            else
+            {
+                // If E=0 and F is zero and S is 1, then V=-0
+                // If E=0 and F is zero and S is 0, then V=0
+
+                // we do not support -0 or 0, only is one 0
+                SetZero();
+            }
+        }
+    }
+
+private:
+
+    void FromDouble_SetExpAndMan(bool is_sign, sint e, uint mhighest, uint m)
+    {
+        exponent = e;
+        mantissa.table[man-1] = m | mhighest;
+
+        for(uint i=0 ; i<man-1 ; ++i)
+            mantissa.table[i] = 0;
+
+        info = 0;
+
+        // the value should be different from zero
+        TTMATH_ASSERT( mantissa.IsZero() == false )
+
+        if( is_sign )
+            SetSign();
+    }
+
+#endif
+
+
+public:
+
+
+
+    /*!
+        this method converts from this class into the 'double'
+
+        if the value is too big:
+            'result' will be +/-infinity (depending on the sign)
+            and the method returns 1
+        if the value is too small:
+            'result' will be 0
+            and the method returns 1
+    */
+    uint ToDouble(double & result) const
+    {
+        // sizeof(double) should be 8 (64 bits), this is actually not a runtime
+        // error but I leave it at the moment as is
+        TTMATH_ASSERT( sizeof(double) == 8 )
+
+        if( IsZero() )
+        {
+            result = 0.0;
+            return 0;
+        }
+
+        if( IsNan() )
+        {
+            result = ToDouble_SetDouble( false, 2047, 0, false, true);
+
+        return 0;
+        }
+
+        sint e_correction = sint(man*TTMATH_BITS_PER_UINT) - 1;
+
+        if( exponent >= 1024 - e_correction )
+        {
+            // +/- infinity
+            result = ToDouble_SetDouble( 0, 2047, 0, true);
+
+        return 1;
+        }
+        else
+        if( exponent <= -1023 - 52 - e_correction )
+        {
+            // too small value - we assume that there'll be a zero
+            result = 0;
+
+            // and return a carry
+        return 1;
+        }
+
+        sint e = exponent.ToInt() + e_correction;
+
+        if( e <= -1023 )
+        {
+            // -1023-52 < e <= -1023  (unnormalized value)
+            result = ToDouble_SetDouble( IsSign(), 0, -(e + 1023));
+        }
+        else
+        {
+            // -1023 < e < 1024
+            result = ToDouble_SetDouble( IsSign(), e + 1023, -1);
+        }
+
+    return 0;
+    }
+
+private:
+
+#ifdef TTMATH_PLATFORM32
+
+    // 32bit platforms
+    double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
+    {
+        union
+        {
+            double d;
+            uint u[2]; // two 32bit words
+        } temp;
+
+        temp.u[0] = temp.u[1] = 0;
+
+        if( is_sign )
+            temp.u[1] |= 0x80000000u;
+
+        temp.u[1] |= (e << 20) & 0x7FF00000u;
+
+        if( nan )
+        {
+            temp.u[0] |= 1;
+            return temp.d;
+        }
+
+        if( infinity )
+            return temp.d;
+
+        UInt<2> m;
+        m.table[1] = mantissa.table[man-1];
+        m.table[0] = ( man > 1 ) ? mantissa.table[sint(man-2)] : 0;
+        // although man>1 we're using casting into sint
+        // to get rid from a warning which generates Microsoft Visual:
+        // warning C4307: '*' : integral constant overflow
+
+        m.Rcr( 12 + move );
+        m.table[1] &= 0xFFFFFu; // cutting the 20 bit (when 'move' was -1)
+
+        temp.u[1] |= m.table[1];
+        temp.u[0] |= m.table[0];
+
+    return temp.d;
+    }
+
+#else
+
+    // 64bit platforms
+    double ToDouble_SetDouble(bool is_sign, uint e, sint move, bool infinity = false, bool nan = false) const
+    {
+        union
+        {
+            double d;
+            uint u; // 64bit word
+        } temp;
+
+        temp.u = 0;
+
+        if( is_sign )
+            temp.u |= 0x8000000000000000ul;
+
+        temp.u |= (e << 52) & 0x7FF0000000000000ul;
+
+        if( nan )
+        {
+            temp.u |= 1;
+            return temp.d;
+        }
+
+        if( infinity )
+            return temp.d;
+
+        uint m = mantissa.table[man-1];
+
+        m >>= ( 12 + move );
+        m &= 0xFFFFFFFFFFFFFul; // cutting the 20 bit (when 'move' was -1)
+        temp.u |= m;
+
+    return temp.d;
+    }
+
+#endif
+
+
+public:
+
+
+    /*!
+        an operator= for converting 'sint' to this class
+    */
+    Big<exp, man> & operator=(sint value)
+    {
+        FromInt(value);
+
+    return *this;
+    }
+
+
+    /*!
+        an operator= for converting 'uint' to this class
+    */
+    Big<exp, man> & operator=(uint value)
+    {
+        FromUInt(value);
+
+    return *this;
+    }
+
+
+    /*!
+        an operator= for converting 'double' to this class
+    */
+    Big<exp, man> & operator=(double value)
+    {
+        FromDouble(value);
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting 'sint' to this class
+    */
+    Big(sint value)
+    {
+        FromInt(value);
+    }
+
+    /*!
+        a constructor for converting 'uint' to this class
+    */
+    Big(uint value)
+    {
+        FromUInt(value);
+    }
+
+
+    /*!
+        a constructor for converting 'double' to this class
+    */
+    Big(double value)
+    {
+        FromDouble(value);
+    }
+
+
+#ifdef TTMATH_PLATFORM64
+
+    /*!
+        in 64bit platforms we must define additional operators and contructors
+        in order to allow a user initializing the objects in this way:
+            Big<...> type = 20;
+        or
+            Big<...> type;
+            type = 30;
+
+        decimal constants such as 20, 30 etc. are integer literal of type int,
+        if the value is greater it can even be long int,
+        0 is an octal integer of type int
+        (ISO 14882 p2.13.1 Integer literals)
+    */
+
+    /*!
+        an operator= for converting 'signed int' to this class
+        ***this operator is created only on a 64bit platform***
+        it takes one argument of 32bit
+
+
+    */
+    Big<exp, man> & operator=(signed int value)
+    {
+        FromInt(sint(value));
+
+    return *this;
+    }
+
+
+    /*!
+        an operator= for converting 'unsigned int' to this class
+        ***this operator is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    Big<exp, man> & operator=(unsigned int value)
+    {
+        FromUInt(uint(value));
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting 'signed int' to this class
+        ***this constructor is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    Big(signed int value)
+    {
+        FromInt(sint(value));
+    }
+
+    /*!
+        a constructor for converting 'unsigned int' to this class
+        ***this constructor is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    Big(unsigned int value)
+    {
+        FromUInt(uint(value));
+    }
+
+#endif
+
+private:
+
+    /*!
+        an auxiliary method for converting from UInt and Int
+
+        we assume that there'll never be a carry here
+        (we have an exponent and the value in Big can be bigger than
+        that one from the UInt)
+    */
+    template<uint int_size>
+    void FromUIntOrInt(const UInt<int_size> & value, sint compensation)
+    {
+        uint minimum_size = (int_size < man)? int_size : man;
+        exponent          = (sint(int_size)-sint(man)) * sint(TTMATH_BITS_PER_UINT) - compensation;
+
+        // copying the highest words
+        uint i;
+        for(i=1 ; i<=minimum_size ; ++i)
+            mantissa.table[man-i] = value.table[int_size-i];
+
+        // setting the rest of mantissa.table into zero (if some has left)
+        for( ; i<=man ; ++i)
+            mantissa.table[man-i] = 0;
+
+        // the highest bit is either one or zero (when the whole mantissa is zero)
+        // we can only call CorrectZero()
+        CorrectZero();
+    }
+
+
+public:
+
+
+    /*!
+        a method for converting from 'UInt<int_size>' to this class
+    */
+    template<uint int_size>
+    void FromUInt(UInt<int_size> value)
+    {
+        info = 0;
+        sint compensation = (sint)value.CompensationToLeft();
+
+    return FromUIntOrInt(value, compensation);
+    }
+
+
+    /*!
+        a method for converting from 'Int<int_size>' to this class
+    */
+    template<uint int_size>
+    void FromInt(Int<int_size> value)
+    {
+        info = 0;
+        bool is_sign = false;
+
+        if( value.IsSign() )
+        {
+            value.ChangeSign();
+            is_sign = true;
+        }
+
+        sint compensation = (sint)value.CompensationToLeft();
+        FromUIntOrInt(value, compensation);
+
+        if( is_sign )
+            SetSign();
+    }
+
+
+    /*!
+        an operator= for converting from 'Int<int_size>' to this class
+    */
+    template<uint int_size>
+    Big<exp,man> & operator=(const Int<int_size> & value)
+    {
+        FromInt(value);
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting from 'Int<int_size>' to this class
+    */
+    template<uint int_size>
+    Big(const Int<int_size> & value)
+    {
+        FromInt(value);
+    }
+
+
+    /*!
+        an operator= for converting from 'UInt<int_size>' to this class
+    */
+    template<uint int_size>
+    Big<exp,man> & operator=(const UInt<int_size> & value)
+    {
+        FromUInt(value);
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting from 'UInt<int_size>' to this class
+    */
+    template<uint int_size>
+    Big(const UInt<int_size> & value)
+    {
+        FromUInt(value);
+    }
+
+
+    /*!
+        an operator= for converting from 'Big<another_exp, another_man>' to this class
+    */
+    template<uint another_exp, uint another_man>
+    Big<exp,man> & operator=(const Big<another_exp, another_man> & value)
+    {
+        FromBig(value);
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting from 'Big<another_exp, another_man>' to this class
+    */
+    template<uint another_exp, uint another_man>
+    Big(const Big<another_exp, another_man> & value)
+    {
+        FromBig(value);
+    }
+
+
+    /*!
+        a default constructor
+
+        we don't set any of the members to zero
+        only NaN flag is set
+    */
+    Big()
+    {
+        info = TTMATH_BIG_NAN;
+
+        /*
+            we're directly setting 'info' (instead of calling SetNan())
+            in order to get rid of a warning saying that 'info' is uninitialized
+        */
+    }
+
+
+    /*!
+        a destructor
+    */
+    ~Big()
+    {
+    }
+
+
+    /*!
+        the default assignment operator
+    */
+    Big<exp,man> & operator=(const Big<exp,man> & value)
+    {
+        info     = value.info;
+        exponent = value.exponent;
+        mantissa = value.mantissa;
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for copying from another object of this class
+    */
+
+    Big(const Big<exp,man> & value)
+    {
+        operator=(value);
+    }
+
+
+
+    /*!
+        a method for converting into a string
+        struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+
+        output:
+            return value:
+            0 - ok and 'result' will be an object of type std::string (or std::wstring) which holds the value
+            1 - if there is a carry (it shoudn't be in a normal situation - if it is that means there
+                is somewhere an error in the library)
+    */
+    uint ToString(  std::string & result,
+                    uint base         = 10,
+                    bool scient       = false,
+                    sint scient_from  = 15,
+                    sint round        = -1,
+                    bool trim_zeroes  = true,
+                    wchar_t comma     = '.' ) const
+    {
+        Conv conv;
+
+        conv.base         = base;
+        conv.scient       = scient;
+        conv.scient_from  = scient_from;
+        conv.round        = round;
+        conv.trim_zeroes  = trim_zeroes;
+        conv.comma        = static_cast<uint>(comma);
+
+    return ToStringBase<std::string, char>(result, conv);
+    }
+
+
+    /*!
+        a method for converting into a string
+        struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+    */
+    uint ToString(  std::wstring & result,
+                    uint base         = 10,
+                    bool scient       = false,
+                    sint scient_from  = 15,
+                    sint round        = -1,
+                    bool trim_zeroes  = true,
+                    wchar_t comma     = '.' ) const
+    {
+        Conv conv;
+
+        conv.base         = base;
+        conv.scient       = scient;
+        conv.scient_from  = scient_from;
+        conv.round        = round;
+        conv.trim_zeroes  = trim_zeroes;
+        conv.comma        = static_cast<uint>(comma);
+
+    return ToStringBase<std::wstring, wchar_t>(result, conv);
+    }
+
+
+    /*!
+        a method for converting into a string
+        struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+    */
+    uint ToString(std::string & result, const Conv & conv) const
+    {
+        return ToStringBase<std::string, char>(result, conv);
+    }
+
+
+    /*!
+        a method for converting into a string
+        struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+    */
+    uint ToString(std::wstring & result, const Conv & conv) const
+    {
+        return ToStringBase<std::wstring, wchar_t>(result, conv);
+    }
+
+
+    /*!
+        a method for converting into a string
+        struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+    */
+    std::string ToString(const Conv & conv) const
+    {
+        std::string result;
+        ToStringBase<std::string, char>(result, conv);
+
+    return result;
+    }
+
+
+    /*!
+        a method for converting into a string
+        struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+    */
+    std::string ToString() const
+    {
+        Conv conv;
+
+    return ToString(conv);
+    }
+
+
+    /*!
+        a method for converting into a string
+        struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+    */
+    std::wstring ToWString(const Conv & conv) const
+    {
+        std::wstring result;
+        ToStringBase<std::wstring, wchar_t>(result, conv);
+
+    return result;
+    }
+
+
+    /*!
+        a method for converting into a string
+        struct Conv is defined in ttmathtypes.h, look there for more information about parameters
+    */
+    std::wstring ToWString() const
+    {
+        Conv conv;
+
+    return ToWString(conv);
+    }
+
+
+private:
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    uint ToStringBase(string_type & result, const Conv & conv) const
+    {
+        static char error_overflow_msg[] = "overflow";
+        static char error_nan_msg[]      = "NaN";
+        result.erase();
+
+        if( IsNan() )
+        {
+            Misc::AssignString(result, error_nan_msg);
+            return 0;
+        }
+
+        if( conv.base<2 || conv.base>16 )
+        {
+            Misc::AssignString(result, error_overflow_msg);
+            return 1;
+        }
+
+        if( IsZero() )
+        {
+            result = '0';
+
+        return 0;
+        }
+
+        /*
+            since 'base' is greater or equal 2 that 'new_exp' of type 'Int<exp>' should
+            hold the new value of exponent but we're using 'Int<exp+1>' because
+            if the value for example would be 'max()' then we couldn't show it
+
+                max() ->  11111111 * 2 ^ 11111111111  (bin)(the mantissa and exponent have all bits set)
+                if we were using 'Int<exp>' we couldn't show it in this format:
+                1,1111111 * 2 ^ 11111111111  (bin)
+                because we have to add something to the mantissa and because
+                mantissa is full we can't do it and it'll be a carry
+                (look at ToString_SetCommaAndExponent(...))
+
+                when the base would be greater than two (for example 10)
+                we could use 'Int<exp>' here
+        */
+        Int<exp+1> new_exp;
+
+        if( ToString_CreateNewMantissaAndExponent<string_type, char_type>(result, conv, new_exp) )
+        {
+            Misc::AssignString(result, error_overflow_msg);
+            return 1;
+        }
+
+
+        if( ToString_SetCommaAndExponent<string_type, char_type>(result, conv, new_exp) )
+        {
+            Misc::AssignString(result, error_overflow_msg);
+            return 1;
+        }
+
+        if( IsSign() )
+            result.insert(result.begin(), '-');
+
+
+    // converted successfully
+    return 0;
+    }
+
+
+
+    /*!
+        in the method 'ToString_CreateNewMantissaAndExponent()' we're using
+        type 'Big<exp+1,man>' and we should have the ability to use some
+        necessary methods from that class (methods which are private here)
+    */
+    friend class Big<exp-1,man>;
+
+
+    /*!
+        an auxiliary method for converting into the string
+
+        input:
+            base - the base in range <2,16>
+
+        output:
+            return values:
+                0 - ok
+                1 - if there was a carry
+            new_man - the new mantissa for 'base'
+            new_exp - the new exponent for 'base'
+
+        mathematic part:
+
+        the value is stored as:
+            value = mantissa * 2^exponent
+        we want to show 'value' as:
+            value = new_man * base^new_exp
+
+        then 'new_man' we'll print using the standard method from UInt<> type for printing
+        and 'new_exp' is the offset of the comma operator in a system of a base 'base'
+
+        value = mantissa * 2^exponent
+        value = mantissa * 2^exponent * (base^new_exp / base^new_exp)
+        value = mantissa * (2^exponent / base^new_exp) * base^new_exp
+
+        look at the part (2^exponent / base^new_exp), there'll be good if we take
+        a 'new_exp' equal that value when the (2^exponent / base^new_exp) will be equal one
+
+        on account of the 'base' is not as power of 2 (can be from 2 to 16),
+        this formula will not be true for integer 'new_exp' then in our case we take
+        'base^new_exp' _greater_ than '2^exponent'
+
+        if 'base^new_exp' were smaller than '2^exponent' the new mantissa could be
+        greater than the max value of the container UInt<man>
+
+        value = mantissa * (2^exponent / base^new_exp) * base^new_exp
+          let M = mantissa * (2^exponent / base^new_exp) then
+        value = M * base^new_exp
+
+        in our calculation we treat M as floating value showing it as:
+            M = mm * 2^ee where ee will be <= 0
+
+        next we'll move all bits of mm into the right when ee is equal zero
+        abs(ee) must not be too big that only few bits from mm we can leave
+
+        then we'll have:
+            M = mmm * 2^0
+        'mmm' is the new_man which we're looking for
+
+
+        new_exp we calculate in this way:
+            2^exponent <= base^new_exp
+            new_exp >= log base (2^exponent)   <- logarithm with the base 'base' from (2^exponent)
+
+            but we need new_exp as integer then we test:
+            if new_exp is greater than zero and with fraction we add one to new_exp
+              new_exp = new_exp + 1    (if new_exp>0 and with fraction)
+            and at the end we take the integer part:
+              new_exp = int(new_exp)
+    */
+    template<class string_type, class char_type>
+    uint ToString_CreateNewMantissaAndExponent( string_type & new_man, const Conv & conv,
+                                                Int<exp+1> & new_exp) const
+    {
+    uint c = 0;
+
+        if( conv.base<2 || conv.base>16 )
+            return 1;
+
+        // the speciality for base equal 2
+        if( conv.base == 2 )
+            return ToString_CreateNewMantissaAndExponent_Base2(new_man, new_exp);
+
+        // the speciality for base equal 4
+        if( conv.base == 4 )
+            return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 2);
+
+        // the speciality for base equal 8
+        if( conv.base == 8 )
+            return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 3);
+
+        // the speciality for base equal 16
+        if( conv.base == 16 )
+            return ToString_CreateNewMantissaAndExponent_BasePow2(new_man, new_exp, 4);
+
+
+        // this = mantissa * 2^exponent
+
+        // temp = +1 * 2^exponent
+        // we're using a bigger type than 'big<exp,man>' (look below)
+        Big<exp+1,man> temp;
+        temp.info = 0;
+        temp.exponent = exponent;
+        temp.mantissa.SetOne();
+        c += temp.Standardizing();
+
+        // new_exp_ = log base (2^exponent)
+        // if new_exp_ is positive and with fraction then we add one
+        Big<exp+1,man> new_exp_;
+        c += new_exp_.ToString_Log(temp, conv.base); // this logarithm isn't very complicated
+
+        // adding some epsilon value (to get rid of some floating point errors)
+        temp.Set05();
+        temp.exponent.SubOne(); // temp = 0.5/2 = 0.25
+        c += new_exp_.Add(temp);
+
+        if( !new_exp_.IsSign() && !new_exp_.IsInteger() )
+        {
+            // new_exp_ > 0 and with fraction
+            temp.SetOne();
+            c += new_exp_.Add( temp );
+        }
+
+        // new_exp_ = int(new_exp_)
+        new_exp_.SkipFraction();
+
+
+        // because 'base^new_exp' is >= '2^exponent' then
+        // because base is >= 2 then we've got:
+        // 'new_exp_' must be smaller or equal 'new_exp'
+        // and we can pass it into the Int<exp> type
+        // (in fact we're using a greater type then it'll be ok)
+        c += new_exp_.ToInt(new_exp);
+
+        // base_ = base
+        Big<exp+1,man> base_(conv.base);
+
+        // base_ = base_ ^ new_exp_
+        c += base_.Pow( new_exp_ );
+        // if we hadn't used a bigger type than 'Big<exp,man>' then the result
+        // of this formula 'Pow(...)' would have been with an overflow
+
+        // temp = mantissa * 2^exponent / base_^new_exp_
+        // the sign don't interest us here
+        temp.mantissa = mantissa;
+        temp.exponent = exponent;
+        c += temp.Div(base_, false); // dividing without rounding
+
+        // moving all bits of the mantissa into the right
+        // (how many times to move depend on the exponent)
+        c += temp.ToString_MoveMantissaIntoRight();
+
+        // because we took 'new_exp' as small as it was
+        // possible ([log base (2^exponent)] + 1) that after the division
+        // (temp.Div( base_ )) the value of exponent should be equal zero or
+        // minimum smaller than zero then we've got the mantissa which has
+        // maximum valid bits
+        temp.mantissa.ToString(new_man, conv.base);
+
+        // base rounding
+        if( conv.base_round )
+            c += ToString_BaseRound<string_type, char_type>(new_man, conv, new_exp);
+
+    return (c==0)? 0 : 1;
+    }
+
+
+    /*!
+        this method calculates the logarithm
+        it is used by ToString_CreateNewMantissaAndExponent() method
+
+        it's not too complicated
+        because x=+1*2^exponent (mantissa is one) then during the calculation
+        the Ln(x) will not be making the long formula from LnSurrounding1()
+        and only we have to calculate 'Ln(base)' but it'll be calculated
+        only once, the next time we will get it from the 'history'
+
+        x is greater than 0
+        base is in <2,16> range
+    */
+    uint ToString_Log(const Big<exp,man> & x, uint base)
+    {
+        TTMATH_REFERENCE_ASSERT( x )
+        TTMATH_ASSERT( base>=2 && base<=16 )
+
+        Big<exp,man> temp;
+        temp.SetOne();
+
+        if( x == temp )
+        {
+            // log(1) is 0
+            SetZero();
+
+        return 0;
+        }
+
+        // there can be only a carry
+        // because the 'x' is in '1+2*exponent' form then
+        // the long formula from LnSurrounding1() will not be calculated
+        // (LnSurrounding1() will return one immediately)
+        uint c = Ln(x);
+
+        if( base==10 && man<=TTMATH_BUILTIN_VARIABLES_SIZE )
+        {
+            // for the base equal 10 we're using SelLn10() instead of calculating it
+            // (only if we have the constant sufficient big)
+            temp.SetLn10();
+        }
+        else
+        {
+            c += ToString_LogBase(base, temp);
+        }
+
+        c += Div( temp );
+
+    return (c==0)? 0 : 1;
+    }
+
+
+#ifndef TTMATH_MULTITHREADS
+
+    /*!
+        this method calculates the logarithm of 'base'
+        it's used in single thread environment
+    */
+    uint ToString_LogBase(uint base, Big<exp,man> & result)
+    {
+        TTMATH_ASSERT( base>=2 && base<=16 )
+
+        // this guardians are initialized before the program runs (static POD types)
+        static int guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+        static Big<exp,man> log_history[15];
+        uint index = base - 2;
+        uint c = 0;
+
+        if( guardians[index] == 0 )
+        {
+            Big<exp,man> base_(base);
+            c += log_history[index].Ln(base_);
+            guardians[index] = 1;
+        }
+
+        result = log_history[index];
+
+    return (c==0)? 0 : 1;
+    }
+
+#else
+
+    /*!
+        this method calculates the logarithm of 'base'
+        it's used in multi-thread environment
+    */
+    uint ToString_LogBase(uint base, Big<exp,man> & result)
+    {
+        TTMATH_ASSERT( base>=2 && base<=16 )
+
+        // this guardians are initialized before the program runs (static POD types)
+        volatile static sig_atomic_t guardians[15] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+        static Big<exp,man> * plog_history;
+        uint index = base - 2;
+        uint c = 0;
+
+        // double-checked locking
+        if( guardians[index] == 0 )
+        {
+            ThreadLock thread_lock;
+
+            // locking
+            if( thread_lock.Lock() )
+            {
+                static Big<exp,man> log_history[15];
+
+                if( guardians[index] == 0 )
+                {
+                    plog_history = log_history;
+
+                    Big<exp,man> base_(base);
+                    c += log_history[index].Ln(base_);
+                    guardians[index] = 1;
+                }
+            }
+            else
+            {
+                // there was a problem with locking, we store the result directly in 'result' object
+                Big<exp,man> base_(base);
+                c += result.Ln(base_);
+
+            return (c==0)? 0 : 1;
+            }
+
+            // automatically unlocking
+        }
+
+        result = plog_history[index];
+
+    return (c==0)? 0 : 1;
+    }
+
+#endif
+
+    /*!
+        an auxiliary method for converting into the string (private)
+
+        this method moving all bits from mantissa into the right side
+        the exponent tell us how many times moving (the exponent is <=0)
+    */
+    uint ToString_MoveMantissaIntoRight()
+    {
+        if( exponent.IsZero() )
+            return 0;
+
+        // exponent can't be greater than zero
+        // because we would cat the highest bits of the mantissa
+        if( !exponent.IsSign() )
+            return 1;
+
+
+        if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
+            // if 'exponent' is <= than '-sint(man*TTMATH_BITS_PER_UINT)'
+            // it means that we must cut the whole mantissa
+            // (there'll not be any of the valid bits)
+            return 1;
+
+        // e will be from (-man*TTMATH_BITS_PER_UINT, 0>
+        sint e = -( exponent.ToInt() );
+        mantissa.Rcr(e,0);
+
+    return 0;
+    }
+
+
+    /*!
+        a special method similar to the 'ToString_CreateNewMantissaAndExponent'
+        when the 'base' is equal 2
+
+        we use it because if base is equal 2 we don't have to make those
+        complicated calculations and the output is directly from the source
+        (there will not be any small distortions)
+    */
+    template<class string_type>
+    uint ToString_CreateNewMantissaAndExponent_Base2(   string_type & new_man,
+                                                        Int<exp+1> & new_exp     ) const
+    {
+        for( sint i=man-1 ; i>=0 ; --i )
+        {
+            uint value = mantissa.table[i];
+
+            for( uint bit=0 ; bit<TTMATH_BITS_PER_UINT ; ++bit )
+            {
+                if( (value & TTMATH_UINT_HIGHEST_BIT) != 0 )
+                    new_man += '1';
+                else
+                    new_man += '0';
+
+                value <<= 1;
+            }
+        }
+
+        new_exp = exponent;
+
+    return 0;
+    }
+
+
+    /*!
+        a special method used to calculate the new mantissa and exponent
+        when the 'base' is equal 4, 8 or 16
+
+        when base is 4 then bits is 2
+        when base is 8 then bits is 3
+        when base is 16 then bits is 4
+        (and the algorithm can be used with a base greater than 16)
+    */
+    template<class string_type>
+    uint ToString_CreateNewMantissaAndExponent_BasePow2(    string_type & new_man,
+                                                            Int<exp+1> & new_exp,
+                                                            uint bits) const
+    {
+        sint move;                          // how many times move the mantissa
+        UInt<man+1> man_temp(mantissa);     // man+1 for moving
+        new_exp = exponent;
+        new_exp.DivInt((sint)bits, move);
+
+        if( move != 0 )
+        {
+            // we're moving the man_temp to left-hand side
+            if( move < 0 )
+            {
+                move = sint(bits) + move;
+                new_exp.SubOne();           // when move is < than 0 then new_exp is < 0 too
+            }
+
+            man_temp.Rcl(move);
+        }
+
+
+        if( bits == 3 )
+        {
+            // base 8
+            // now 'move' is greater than or equal 0
+            uint len = man*TTMATH_BITS_PER_UINT + move;
+            return ToString_CreateNewMantissaAndExponent_Base8(new_man, man_temp, len, bits);
+        }
+        else
+        {
+            // base 4 or 16
+            return ToString_CreateNewMantissaAndExponent_Base4or16(new_man, man_temp, bits);
+        }
+    }
+
+
+    /*!
+        a special method used to calculate the new mantissa
+        when the 'base' is equal 8
+
+        bits is always 3
+
+        we can use this algorithm when the base is 4 or 16 too
+        but we have a faster method ToString_CreateNewMantissaAndExponent_Base4or16()
+    */
+    template<class string_type>
+    uint ToString_CreateNewMantissaAndExponent_Base8(   string_type & new_man,
+                                                        UInt<man+1> & man_temp,
+                                                        uint len,
+                                                        uint bits) const
+    {
+        uint shift = TTMATH_BITS_PER_UINT - bits;
+        uint mask  = TTMATH_UINT_MAX_VALUE >> shift;
+        uint i;
+
+        for( i=0 ; i<len ; i+=bits )
+        {
+            uint digit = man_temp.table[0] & mask;
+            new_man.insert(new_man.begin(), static_cast<char>(Misc::DigitToChar(digit)));
+
+            man_temp.Rcr(bits);
+        }
+
+        TTMATH_ASSERT( man_temp.IsZero() )
+
+    return 0;
+    }
+
+
+    /*!
+        a special method used to calculate the new mantissa
+        when the 'base' is equal 4 or 16
+
+        when the base is equal 4 or 16 the bits is 2 or 4
+        and because TTMATH_BITS_PER_UINT (32 or 64) is divisible by 2 (or 4)
+        then we can get digits from the end of our mantissa
+    */
+    template<class string_type>
+    uint ToString_CreateNewMantissaAndExponent_Base4or16(   string_type & new_man,
+                                                            UInt<man+1> & man_temp,
+                                                            uint bits) const
+    {
+        TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 2 == 0 )
+        TTMATH_ASSERT( TTMATH_BITS_PER_UINT % 4 == 0 )
+
+        uint shift = TTMATH_BITS_PER_UINT - bits;
+        uint mask  = TTMATH_UINT_MAX_VALUE << shift;
+        uint digit;
+
+         // table[man] - last word - is different from zero if we moved man_temp
+        digit = man_temp.table[man];
+
+        if( digit != 0 )
+            new_man += static_cast<char>(Misc::DigitToChar(digit));
+
+
+        for( int i=man-1 ; i>=0 ; --i )
+        {
+            uint shift_local = shift;
+            uint mask_local  = mask;
+
+            while( mask_local != 0 )
+            {
+                digit = man_temp.table[i] & mask_local;
+
+                if( shift_local != 0 )
+                    digit = digit >> shift_local;
+
+                new_man    += static_cast<char>(Misc::DigitToChar(digit));
+                mask_local  = mask_local >> bits;
+                shift_local = shift_local - bits;
+            }
+        }
+
+    return 0;
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    bool ToString_RoundMantissaWouldBeInteger(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
+    {
+        // if new_exp is greater or equal to zero then we have an integer value,
+        // if new_exp is equal -1 then we have only one digit after the comma
+        // and after rounding it would be an integer value
+        if( !new_exp.IsSign() || new_exp == -1 )
+            return true;
+
+        if( new_man.size() >= TTMATH_UINT_HIGHEST_BIT || new_man.size() < 2 )
+            return true; // oops, the mantissa is too large for calculating (or too small) - we are not doing the base rounding
+
+        uint i = 0;
+        char_type digit;
+
+        if( new_exp >= -sint(new_man.size()) )
+        {
+            uint new_exp_abs = -new_exp.ToInt();
+            i = new_man.size() - new_exp_abs; // start from the first digit after the comma operator
+        }
+
+        if( Misc::CharToDigit(new_man[new_man.size()-1]) >= conv.base/2 )
+        {
+            if( new_exp < -sint(new_man.size()) )
+            {
+                // there are some zeroes after the comma operator
+                // (between the comma and the first digit from the mantissa)
+                // and the result value will never be an integer
+                return false;
+            }
+
+            digit = static_cast<char_type>( Misc::DigitToChar(conv.base-1) );
+        }
+        else
+        {
+            digit = '0';
+        }
+
+        for( ; i < new_man.size()-1 ; ++i)
+            if( new_man[i] != digit )
+                return false; // it will not be an integer
+
+    return true; // it will be integer after rounding
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+
+        this method is used for base!=2, base!=4, base!=8 and base!=16
+        we do the rounding when the value has fraction (is not an integer)
+    */
+    template<class string_type, class char_type>
+    uint ToString_BaseRound(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
+    {
+        // we must have minimum two characters
+        if( new_man.size() < 2 )
+            return 0;
+
+        // assert that there will not be an integer after rounding
+        if( ToString_RoundMantissaWouldBeInteger<string_type, char_type>(new_man, conv, new_exp) )
+            return 0;
+
+        typename string_type::size_type i = new_man.length() - 1;
+
+        // we're erasing the last character
+        uint digit = Misc::CharToDigit( new_man[i] );
+        new_man.erase(i, 1);
+        uint c = new_exp.AddOne();
+
+        // if the last character is greater or equal 'base/2'
+        // we are adding one into the new mantissa
+        if( digit >= conv.base / 2 )
+            ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
+
+    return c;
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+
+        this method addes one into the new mantissa
+    */
+    template<class string_type, class char_type>
+    void ToString_RoundMantissa_AddOneIntoMantissa(string_type & new_man, const Conv & conv) const
+    {
+        if( new_man.empty() )
+            return;
+
+        sint i = sint( new_man.length() ) - 1;
+        bool was_carry = true;
+
+        for( ; i>=0 && was_carry ; --i )
+        {
+            // we can have the comma as well because
+            // we're using this method later in ToString_CorrectDigitsAfterComma_Round()
+            // (we're only ignoring it)
+            if( new_man[i] == static_cast<char_type>(conv.comma) )
+                continue;
+
+            // we're adding one
+            uint digit = Misc::CharToDigit( new_man[i] ) + 1;
+
+            if( digit == conv.base )
+                digit = 0;
+            else
+                was_carry = false;
+
+            new_man[i] = static_cast<char_type>( Misc::DigitToChar(digit) );
+        }
+
+        if( i<0 && was_carry )
+            new_man.insert( new_man.begin() , '1' );
+    }
+
+
+
+    /*!
+        an auxiliary method for converting into the string
+
+        this method sets the comma operator and/or puts the exponent
+        into the string
+    */
+    template<class string_type, class char_type>
+    uint ToString_SetCommaAndExponent(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp) const
+    {
+    uint carry = 0;
+
+        if( new_man.empty() )
+            return carry;
+
+        Int<exp+1> scientific_exp( new_exp );
+
+        // 'new_exp' depends on the 'new_man' which is stored like this e.g:
+        //  32342343234 (the comma is at the end)
+        // we'd like to show it in this way:
+        //  3.2342343234 (the 'scientific_exp' is connected with this example)
+
+        sint offset = sint( new_man.length() ) - 1;
+        carry += scientific_exp.Add( offset );
+        // there shouldn't have been a carry because we're using
+        // a greater type -- 'Int<exp+1>' instead of 'Int<exp>'
+
+        bool print_scientific = conv.scient;
+
+        if( !print_scientific )
+        {
+            if( scientific_exp > conv.scient_from || scientific_exp < -sint(conv.scient_from) )
+                print_scientific = true;
+        }
+
+        if( !print_scientific )
+            ToString_SetCommaAndExponent_Normal<string_type, char_type>(new_man, conv, new_exp);
+        else
+            // we're passing the 'scientific_exp' instead of 'new_exp' here
+            ToString_SetCommaAndExponent_Scientific<string_type, char_type>(new_man, conv, scientific_exp);
+
+    return (carry==0)? 0 : 1;
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_SetCommaAndExponent_Normal(string_type & new_man, const Conv & conv, Int<exp+1> & new_exp ) const
+    {
+        if( !new_exp.IsSign() ) // it means: if( new_exp >= 0 )
+            ToString_SetCommaAndExponent_Normal_AddingZero<string_type, char_type>(new_man, new_exp);
+        else
+            ToString_SetCommaAndExponent_Normal_SetCommaInside<string_type, char_type>(new_man, conv, new_exp);
+
+
+        ToString_Group_man<string_type, char_type>(new_man, conv);
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_SetCommaAndExponent_Normal_AddingZero(string_type & new_man,
+                                                        Int<exp+1> & new_exp) const
+    {
+        // we're adding zero characters at the end
+        // 'i' will be smaller than 'when_scientific' (or equal)
+        uint i = new_exp.ToInt();
+
+        if( new_man.length() + i > new_man.capacity() )
+            // about 6 characters more (we'll need it for the comma or something)
+            new_man.reserve( new_man.length() + i + 6 );
+
+        for( ; i>0 ; --i)
+            new_man += '0';
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_SetCommaAndExponent_Normal_SetCommaInside(
+                                                            string_type & new_man,
+                                                            const Conv & conv,
+                                                            Int<exp+1> & new_exp ) const
+    {
+        // new_exp is < 0
+
+        sint new_man_len = sint(new_man.length()); // 'new_man_len' with a sign
+        sint e = -( new_exp.ToInt() ); // 'e' will be positive
+
+        if( new_exp > -new_man_len )
+        {
+            // we're setting the comma within the mantissa
+
+            sint index = new_man_len - e;
+            new_man.insert( new_man.begin() + index, static_cast<char_type>(conv.comma));
+        }
+        else
+        {
+            // we're adding zero characters before the mantissa
+
+            uint how_many = e - new_man_len;
+            string_type man_temp(how_many+1, '0');
+
+            man_temp.insert( man_temp.begin()+1, static_cast<char_type>(conv.comma));
+            new_man.insert(0, man_temp);
+        }
+
+        ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_SetCommaAndExponent_Scientific(   string_type & new_man,
+                                                    const Conv & conv,
+                                                    Int<exp+1> & scientific_exp ) const
+    {
+        if( new_man.empty() )
+            return;
+
+        if( new_man.size() > 1 )
+        {
+            new_man.insert( new_man.begin()+1, static_cast<char_type>(conv.comma) );
+            ToString_CorrectDigitsAfterComma<string_type, char_type>(new_man, conv);
+        }
+
+        ToString_Group_man<string_type, char_type>(new_man, conv);
+
+        if( conv.base == 10 )
+        {
+            new_man += 'e';
+
+            if( !scientific_exp.IsSign() )
+                new_man += '+';
+        }
+        else
+        {
+            // the 10 here is meant as the base 'base'
+            // (no matter which 'base' we're using there'll always be 10 here)
+            Misc::AddString(new_man, "*10^");
+        }
+
+        string_type temp_exp;
+        scientific_exp.ToString( temp_exp, conv.base );
+
+        new_man += temp_exp;
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_Group_man(string_type & new_man, const Conv & conv) const
+    {
+        typedef typename string_type::size_type StrSize;
+
+        if( conv.group == 0 )
+            return;
+
+        // first we're looking for the comma operator
+        StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
+
+        if( index == string_type::npos )
+            index = new_man.size();
+
+        ToString_Group_man_before_comma<string_type, char_type>(new_man, conv, index);
+        ToString_Group_man_after_comma<string_type, char_type>(new_man, conv, index+1);
+    }
+
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_Group_man_before_comma(   string_type & new_man, const Conv & conv,
+                                            typename string_type::size_type & index) const
+    {
+    typedef typename string_type::size_type StrSize;
+    uint group = 0;
+
+        StrSize i = index;
+
+        // adding group characters before the comma operator
+        // i>0 because on the first position we don't put any additional grouping characters
+        for( ; i>0 ; --i, ++group)
+        {
+            if( group >= 3 )
+            {
+                group = 0;
+                new_man.insert(i, 1, static_cast<char_type>(conv.group));
+                ++index;
+            }
+        }
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_Group_man_after_comma(string_type & new_man, const Conv & conv,
+                                        typename string_type::size_type index) const
+    {
+    uint group = 0;
+
+        for( ; index<new_man.size() ; ++index, ++group)
+        {
+            if( group >= 3 )
+            {
+                group = 0;
+                new_man.insert(index, 1, static_cast<char_type>(conv.group));
+                ++index;
+            }
+        }
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_CorrectDigitsAfterComma(  string_type & new_man,
+                                            const Conv & conv ) const
+    {
+        if( conv.round >= 0 )
+            ToString_CorrectDigitsAfterComma_Round<string_type, char_type>(new_man, conv);
+
+        if( conv.trim_zeroes )
+            ToString_CorrectDigitsAfterComma_CutOffZeroCharacters<string_type, char_type>(new_man, conv);
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_CorrectDigitsAfterComma_CutOffZeroCharacters(
+                                                string_type & new_man,
+                                                const Conv & conv) const
+    {
+        // minimum two characters
+        if( new_man.length() < 2 )
+            return;
+
+        // we're looking for the index of the last character which is not zero
+        uint i = uint( new_man.length() ) - 1;
+        for( ; i>0 && new_man[i]=='0' ; --i );
+
+        // if there is another character than zero at the end
+        // we're finishing
+        if( i == new_man.length() - 1 )
+            return;
+
+        // we must have a comma
+        // (the comma can be removed by ToString_CorrectDigitsAfterComma_Round
+        // which is called before)
+        if( new_man.find_last_of(static_cast<char_type>(conv.comma), i) == string_type::npos )
+            return;
+
+        // if directly before the first zero is the comma operator
+        // we're cutting it as well
+        if( i>0 && new_man[i]==static_cast<char_type>(conv.comma) )
+            --i;
+
+        new_man.erase(i+1, new_man.length()-i-1);
+    }
+
+
+    /*!
+        an auxiliary method for converting into the string
+    */
+    template<class string_type, class char_type>
+    void ToString_CorrectDigitsAfterComma_Round(
+                                            string_type & new_man,
+                                            const Conv & conv ) const
+    {
+        typedef typename string_type::size_type StrSize;
+
+        // first we're looking for the comma operator
+        StrSize index = new_man.find(static_cast<char_type>(conv.comma), 0);
+
+        if( index == string_type::npos )
+            // nothing was found (actually there can't be this situation)
+            return;
+
+        // we're calculating how many digits there are at the end (after the comma)
+        // 'after_comma' will be greater than zero because at the end
+        // we have at least one digit
+        StrSize after_comma = new_man.length() - index - 1;
+
+        // if 'max_digit_after_comma' is greater than 'after_comma' (or equal)
+        // we don't have anything for cutting
+        if( static_cast<StrSize>(conv.round) >= after_comma )
+            return;
+
+        uint last_digit = Misc::CharToDigit( new_man[ index + conv.round + 1 ], conv.base );
+
+        // we're cutting the rest of the string
+        new_man.erase(index + conv.round + 1, after_comma - conv.round);
+
+        if( conv.round == 0 )
+        {
+            // we're cutting the comma operator as well
+            // (it's not needed now because we've cut the whole rest after the comma)
+            new_man.erase(index, 1);
+        }
+
+        if( last_digit >= conv.base / 2 )
+            // we must round here
+            ToString_RoundMantissa_AddOneIntoMantissa<string_type, char_type>(new_man, conv);
+    }
+
+
+
+public:
+
+    /*!
+        a method for converting a string into its value
+
+        it returns 1 if the value is too big -- we cannot pass it into the range
+        of our class Big<exp,man> (or if the base is incorrect)
+
+        that means only digits before the comma operator can make this value too big,
+        all digits after the comma we can ignore
+
+        'source' - pointer to the string for parsing
+
+        if 'after_source' is set that when this method finishes
+        it sets the pointer to the new first character after parsed value
+
+        'value_read' - if the pointer is provided that means the value_read will be true
+        only when a value has been actually read, there can be situation where only such
+        a string '-' or '+' will be parsed -- 'after_source' will be different from 'source' but
+        no value has been read (there are no digits)
+        on other words if 'value_read' is true -- there is at least one digit in the string
+    */
+    uint FromString(const char * source, uint base = 10, const char ** after_source = 0, bool * value_read = 0)
+    {
+        Conv conv;
+        conv.base = base;
+
+        return FromStringBase(source, conv, after_source, value_read);
+    }
+
+
+    /*!
+        a method for converting a string into its value
+    */
+    uint FromString(const wchar_t * source, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+    {
+        Conv conv;
+        conv.base = base;
+
+        return FromStringBase(source, conv, after_source, value_read);
+    }
+
+
+    /*!
+        a method for converting a string into its value
+    */
+    uint FromString(const char * source, const Conv & conv, const char ** after_source = 0, bool * value_read = 0)
+    {
+        return FromStringBase(source, conv, after_source, value_read);
+    }
+
+
+    /*!
+        a method for converting a string into its value
+    */
+    uint FromString(const wchar_t * source, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
+    {
+        return FromStringBase(source, conv, after_source, value_read);
+    }
+
+
+    /*!
+        a method for converting a string into its value
+    */
+    uint FromString(const std::string & string, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+    {
+        return FromString(string.c_str(), base, after_source, value_read);
+    }
+
+
+    /*!
+        a method for converting a string into its value
+    */
+    uint FromString(const std::wstring & string, uint base = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+    {
+        return FromString(string.c_str(), base, after_source, value_read);
+    }
+
+
+    /*!
+        a method for converting a string into its value
+    */
+    uint FromString(const std::string & string, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
+    {
+        return FromString(string.c_str(), conv, after_source, value_read);
+    }
+
+
+    /*!
+        a method for converting a string into its value
+    */
+    uint FromString(const std::wstring & string, const Conv & conv, const wchar_t ** after_source = 0, bool * value_read = 0)
+    {
+        return FromString(string.c_str(), conv, after_source, value_read);
+    }
+
+private:
+
+
+    /*!
+        an auxiliary method for converting from a string
+    */
+    template<class char_type>
+    uint FromStringBase(const char_type * source, const Conv & conv, const char_type ** after_source = 0, bool * value_read = 0)
+    {
+    bool is_sign;
+    bool value_read_temp = false;
+
+        if( conv.base<2 || conv.base>16 )
+        {
+            SetNan();
+
+            if( after_source )
+                *after_source = source;
+
+            if( value_read )
+                *value_read = value_read_temp;
+
+            return 1;
+        }
+
+        SetZero();
+        FromString_TestSign( source, is_sign );
+
+        uint c = FromString_ReadPartBeforeComma( source, conv, value_read_temp );
+
+        if( FromString_TestCommaOperator(source, conv) )
+            c += FromString_ReadPartAfterComma( source, conv, value_read_temp );
+
+        if( value_read_temp && conv.base == 10 )
+            c += FromString_ReadScientificIfExists( source );
+
+        if( is_sign && !IsZero() )
+            ChangeSign();
+
+        if( after_source )
+            *after_source = source;
+
+        if( value_read )
+            *value_read = value_read_temp;
+
+    return CheckCarry(c);
+    }
+
+
+    /*!
+        we're testing whether the value is with the sign
+
+        (this method is used from 'FromString_ReadPartScientific' too)
+    */
+    template<class char_type>
+    void FromString_TestSign( const char_type * & source, bool & is_sign )
+    {
+        Misc::SkipWhiteCharacters(source);
+
+        is_sign = false;
+
+        if( *source == '-' )
+        {
+            is_sign = true;
+            ++source;
+        }
+        else
+        if( *source == '+' )
+        {
+            ++source;
+        }
+    }
+
+
+    /*!
+        we're testing whether there's a comma operator
+    */
+    template<class char_type>
+    bool FromString_TestCommaOperator(const char_type * & source, const Conv & conv)
+    {
+        if( (*source == static_cast<char_type>(conv.comma)) ||
+            (*source == static_cast<char_type>(conv.comma2) && conv.comma2 != 0 ) )
+        {
+            ++source;
+
+        return true;
+        }
+
+    return false;
+    }
+
+
+    /*!
+        this method reads the first part of a string
+        (before the comma operator)
+    */
+    template<class char_type>
+    uint FromString_ReadPartBeforeComma( const char_type * & source, const Conv & conv, bool & value_read )
+    {
+        sint character;
+        Big<exp, man> temp;
+        Big<exp, man> base_( conv.base );
+
+        Misc::SkipWhiteCharacters( source );
+
+        for( ; true ; ++source )
+        {
+            if( conv.group!=0 && *source==static_cast<char>(conv.group) )
+                continue;
+
+            character = Misc::CharToDigit(*source, conv.base);
+
+            if( character == -1 )
+                break;
+
+            value_read = true;
+            temp = character;
+
+            if( Mul(base_) )
+                return 1;
+
+            if( Add(temp) )
+                return 1;
+        }
+
+    return 0;
+    }
+
+
+    /*!
+        this method reads the second part of a string
+        (after the comma operator)
+    */
+    template<class char_type>
+    uint FromString_ReadPartAfterComma( const char_type * & source, const Conv & conv, bool & value_read )
+    {
+    sint character;
+    uint c = 0, index = 1;
+    Big<exp, man> sum, part, power, old_value, base_( conv.base );
+
+        // we don't remove any white characters here
+
+        // this is only to avoid getting a warning about an uninitialized object 'old_value' which GCC reports
+        // (in fact we will initialize it later when the condition 'testing' is fulfilled)
+        old_value.SetZero();
+
+        power.SetOne();
+        sum.SetZero();
+
+        for( ; true ; ++source, ++index )
+        {
+            if( conv.group!=0 && *source==static_cast<char>(conv.group) )
+                continue;
+
+            character = Misc::CharToDigit(*source, conv.base);
+
+            if( character == -1 )
+                break;
+
+            value_read = true;
+
+            part = character;
+
+            if( power.Mul( base_ ) )
+                // there's no sens to add the next parts, but we can't report this
+                // as an error (this is only inaccuracy)
+                break;
+
+            if( part.Div( power ) )
+                break;
+
+            // every 5 iteration we make a test whether the value will be changed or not
+            // (character must be different from zero to this test)
+            bool testing = (character != 0 && (index % 5) == 0);
+
+            if( testing )
+                old_value = sum;
+
+            // there actually shouldn't be a carry here
+            c += sum.Add( part );
+
+            if( testing && old_value == sum )
+                // after adding 'part' the value has not been changed
+                // there's no sense to add any next parts
+                break;
+        }
+
+        // we could break the parsing somewhere in the middle of the string,
+        // but the result (value) still can be good
+        // we should set a correct value of 'source' now
+        for( ; Misc::CharToDigit(*source, conv.base) != -1 ; ++source );
+
+        c += Add(sum);
+
+    return (c==0)? 0 : 1;
+    }
+
+
+    /*!
+        this method checks whether there is a scientific part: [e|E][-|+]value
+
+        it is called when the base is 10 and some digits were read before
+    */
+    template<class char_type>
+    uint FromString_ReadScientificIfExists(const char_type * & source)
+    {
+    uint c = 0;
+
+        bool scientific_read = false;
+        const char_type * before_scientific = source;
+
+        if( FromString_TestScientific(source) )
+            c += FromString_ReadPartScientific( source, scientific_read );
+
+        if( !scientific_read )
+            source = before_scientific;
+
+    return (c==0)? 0 : 1;
+    }
+
+
+
+    /*!
+        we're testing whether is there the character 'e'
+
+        this character is only allowed when we're using the base equals 10
+    */
+    template<class char_type>
+    bool FromString_TestScientific(const char_type * & source)
+    {
+        Misc::SkipWhiteCharacters(source);
+
+        if( *source=='e' || *source=='E' )
+        {
+            ++source;
+
+        return true;
+        }
+
+    return false;
+    }
+
+
+    /*!
+        this method reads the exponent (after 'e' character) when there's a scientific
+        format of value and only when we're using the base equals 10
+    */
+    template<class char_type>
+    uint FromString_ReadPartScientific( const char_type * & source, bool & scientific_read )
+    {
+    uint c = 0;
+    Big<exp, man> new_exponent, temp;
+    bool was_sign = false;
+
+        FromString_TestSign( source, was_sign );
+        c += FromString_ReadPartScientific_ReadExponent( source, new_exponent, scientific_read );
+
+        if( scientific_read )
+        {
+            if( was_sign )
+                new_exponent.ChangeSign();
+
+            temp = 10;
+            c += temp.Pow( new_exponent );
+            c += Mul(temp);
+        }
+
+    return (c==0)? 0 : 1;
+    }
+
+
+    /*!
+        this method reads the value of the extra exponent when scientific format is used
+        (only when base == 10)
+    */
+    template<class char_type>
+    uint FromString_ReadPartScientific_ReadExponent( const char_type * & source, Big<exp, man> & new_exponent, bool & scientific_read )
+    {
+    sint character;
+    Big<exp, man> base, temp;
+
+        Misc::SkipWhiteCharacters(source);
+
+        new_exponent.SetZero();
+        base = 10;
+
+        for( ; (character=Misc::CharToDigit(*source, 10)) != -1 ; ++source )
+        {
+            scientific_read = true;
+
+            temp = character;
+
+            if( new_exponent.Mul(base) )
+                return 1;
+
+            if( new_exponent.Add(temp) )
+                return 1;
+        }
+
+    return 0;
+    }
+
+
+public:
+
+
+    /*!
+        a constructor for converting a string into this class
+    */
+    Big(const char * string)
+    {
+        FromString( string );
+    }
+
+
+    /*!
+        a constructor for converting a string into this class
+    */
+    Big(const wchar_t * string)
+    {
+        FromString( string );
+    }
+
+
+    /*!
+        a constructor for converting a string into this class
+    */
+    Big(const std::string & string)
+    {
+        FromString( string.c_str() );
+    }
+
+
+    /*!
+        a constructor for converting a string into this class
+    */
+    Big(const std::wstring & string)
+    {
+        FromString( string.c_str() );
+    }
+
+
+    /*!
+        an operator= for converting a string into its value
+    */
+    Big<exp, man> & operator=(const char * string)
+    {
+        FromString( string );
+
+    return *this;
+    }
+
+
+    /*!
+        an operator= for converting a string into its value
+    */
+    Big<exp, man> & operator=(const wchar_t * string)
+    {
+        FromString( string );
+
+    return *this;
+    }
+
+
+    /*!
+        an operator= for converting a string into its value
+    */
+    Big<exp, man> & operator=(const std::string & string)
+    {
+        FromString( string.c_str() );
+
+    return *this;
+    }
+
+
+    /*!
+        an operator= for converting a string into its value
+    */
+    Big<exp, man> & operator=(const std::wstring & string)
+    {
+        FromString( string.c_str() );
+
+    return *this;
+    }
+
+
+
+    /*!
+    *
+    *   methods for comparing
+    *
+    */
+
+
+    /*!
+        this method performs the formula 'abs(this) < abs(ss2)'
+        and returns the result
+
+        (in other words it treats 'this' and 'ss2' as values without a sign)
+        we don't check the NaN flag
+    */
+    bool SmallerWithoutSignThan(const Big<exp,man> & ss2) const
+    {
+        if( IsZero() )
+        {
+            if( ss2.IsZero() )
+                // we've got two zeroes
+                return false;
+            else
+                // this==0 and ss2!=0
+                return true;
+        }
+
+        if( ss2.IsZero() )
+            // this!=0 and ss2==0
+            return false;
+
+        // we're using the fact that all bits in mantissa are pushed
+        // into the left side -- Standardizing()
+        if( exponent == ss2.exponent )
+            return mantissa < ss2.mantissa;
+
+    return exponent < ss2.exponent;
+    }
+
+
+    /*!
+        this method performs the formula 'abs(this) > abs(ss2)'
+        and returns the result
+
+        (in other words it treats 'this' and 'ss2' as values without a sign)
+        we don't check the NaN flag
+    */
+    bool GreaterWithoutSignThan(const Big<exp,man> & ss2) const
+    {
+        if( IsZero() )
+        {
+            if( ss2.IsZero() )
+                // we've got two zeroes
+                return false;
+            else
+                // this==0 and ss2!=0
+                return false;
+        }
+
+        if( ss2.IsZero() )
+            // this!=0 and ss2==0
+            return true;
+
+        // we're using the fact that all bits in mantissa are pushed
+        // into the left side -- Standardizing()
+        if( exponent == ss2.exponent )
+            return mantissa > ss2.mantissa;
+
+    return exponent > ss2.exponent;
+    }
+
+
+    /*!
+        this method performs the formula 'abs(this) == abs(ss2)'
+        and returns the result
+
+        (in other words it treats 'this' and 'ss2' as values without a sign)
+        we don't check the NaN flag
+    */
+    bool EqualWithoutSign(const Big<exp,man> & ss2) const
+    {
+        if( IsZero() )
+        {
+            if( ss2.IsZero() )
+                // we've got two zeroes
+                return true;
+            else
+                // this==0 and ss2!=0
+                return false;
+        }
+
+        if( ss2.IsZero() )
+            // this!=0 and ss2==0
+            return false;
+
+        if( exponent==ss2.exponent && mantissa==ss2.mantissa )
+            return true;
+
+    return false;
+    }
+
+
+    bool operator<(const Big<exp,man> & ss2) const
+    {
+        if( IsSign() && !ss2.IsSign() )
+            // this<0 and ss2>=0
+            return true;
+
+        if( !IsSign() && ss2.IsSign() )
+            // this>=0 and ss2<0
+            return false;
+
+        // both signs are the same
+
+        if( IsSign() )
+            return ss2.SmallerWithoutSignThan( *this );
+
+    return SmallerWithoutSignThan( ss2 );
+    }
+
+
+    bool operator==(const Big<exp,man> & ss2) const
+    {
+        if( IsSign() != ss2.IsSign() )
+            return false;
+
+    return EqualWithoutSign( ss2 );
+    }
+
+
+    bool operator>(const Big<exp,man> & ss2) const
+    {
+        if( IsSign() && !ss2.IsSign() )
+            // this<0 and ss2>=0
+            return false;
+
+        if( !IsSign() && ss2.IsSign() )
+            // this>=0 and ss2<0
+            return true;
+
+        // both signs are the same
+
+        if( IsSign() )
+            return ss2.GreaterWithoutSignThan( *this );
+
+    return GreaterWithoutSignThan( ss2 );
+    }
+
+
+    bool operator>=(const Big<exp,man> & ss2) const
+    {
+        return !operator<( ss2 );
+    }
+
+
+    bool operator<=(const Big<exp,man> & ss2) const
+    {
+        return !operator>( ss2 );
+    }
+
+
+    bool operator!=(const Big<exp,man> & ss2) const
+    {
+        return !operator==(ss2);
+    }
+
+
+
+
+
+    /*!
+    *
+    *   standard mathematical operators
+    *
+    */
+
+
+    /*!
+        an operator for changing the sign
+
+        this method is not changing 'this' but the changed value is returned
+    */
+    Big<exp,man> operator-() const
+    {
+        Big<exp,man> temp(*this);
+
+        temp.ChangeSign();
+
+    return temp;
+    }
+
+
+    Big<exp,man> operator-(const Big<exp,man> & ss2) const
+    {
+    Big<exp,man> temp(*this);
+
+        temp.Sub(ss2);
+
+    return temp;
+    }
+
+    Big<exp,man> & operator-=(const Big<exp,man> & ss2)
+    {
+        Sub(ss2);
+
+    return *this;
+    }
+
+
+    Big<exp,man> operator+(const Big<exp,man> & ss2) const
+    {
+    Big<exp,man> temp(*this);
+
+        temp.Add(ss2);
+
+    return temp;
+    }
+
+
+    Big<exp,man> & operator+=(const Big<exp,man> & ss2)
+    {
+        Add(ss2);
+
+    return *this;
+    }
+
+
+    Big<exp,man> operator*(const Big<exp,man> & ss2) const
+    {
+    Big<exp,man> temp(*this);
+
+        temp.Mul(ss2);
+
+    return temp;
+    }
+
+
+    Big<exp,man> & operator*=(const Big<exp,man> & ss2)
+    {
+        Mul(ss2);
+
+    return *this;
+    }
+
+
+    Big<exp,man> operator/(const Big<exp,man> & ss2) const
+    {
+    Big<exp,man> temp(*this);
+
+        temp.Div(ss2);
+
+    return temp;
+    }
+
+
+    Big<exp,man> & operator/=(const Big<exp,man> & ss2)
+    {
+        Div(ss2);
+
+    return *this;
+    }
+
+
+    /*!
+        this method makes an integer value by skipping any fractions
+
+        for example:
+            10.7 will be 10
+            12.1  -- 12
+            -20.2 -- 20
+            -20.9 -- 20
+            -0.7  -- 0
+            0.8   -- 0
+    */
+    void SkipFraction()
+    {
+        if( IsNan() || IsZero() )
+            return;
+
+        if( !exponent.IsSign() )
+            // exponent >=0 -- the value don't have any fractions
+            return;
+
+        if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
+        {
+            // the value is from (-1,1), we return zero
+            SetZero();
+            return;
+        }
+
+        // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
+        sint e = exponent.ToInt();
+
+        mantissa.ClearFirstBits( -e );
+
+        // we don't have to standardize 'Standardizing()' the value because
+        // there's at least one bit in the mantissa
+        // (the highest bit which we didn't touch)
+    }
+
+
+    /*!
+        this method remains only a fraction from the value
+
+        for example:
+            30.56 will be 0.56
+            -12.67 -- -0.67
+    */
+    void RemainFraction()
+    {
+        if( IsNan() || IsZero() )
+            return;
+
+        if( !exponent.IsSign() )
+        {
+            // exponent >= 0 -- the value doesn't have any fractions
+            // we return zero
+            SetZero();
+            return;
+        }
+
+        if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
+        {
+            // the value is from (-1,1)
+            // we don't make anything with the value
+            return;
+        }
+
+        // e will be from (-man*TTMATH_BITS_PER_UINT, 0)
+        sint e = exponent.ToInt();
+
+        sint how_many_bits_leave = sint(man*TTMATH_BITS_PER_UINT) + e; // there'll be a subtraction -- e is negative
+        mantissa.Rcl( how_many_bits_leave, 0);
+
+        // there'll not be a carry because the exponent is too small
+        exponent.Sub( how_many_bits_leave );
+
+        // we must call Standardizing() here
+        Standardizing();
+    }
+
+
+
+    /*!
+        this method returns true if the value is integer
+        (there is no a fraction)
+
+        (we don't check nan)
+    */
+    bool IsInteger() const
+    {
+        if( IsZero() )
+            return true;
+
+        if( !exponent.IsSign() )
+            // exponent >=0 -- the value don't have any fractions
+            return true;
+
+        if( exponent <= -sint(man*TTMATH_BITS_PER_UINT) )
+            // the value is from (-1,1)
+            return false;
+
+        // exponent is in range (-man*TTMATH_BITS_PER_UINT, 0)
+        sint e = exponent.ToInt();
+        e = -e; // e means how many bits we must check
+
+        uint len  = e / TTMATH_BITS_PER_UINT;
+        uint rest = e % TTMATH_BITS_PER_UINT;
+        uint i    = 0;
+
+        for( ; i<len ; ++i )
+            if( mantissa.table[i] != 0 )
+                return false;
+
+        if( rest > 0 )
+        {
+            uint rest_mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
+            if( (mantissa.table[i] & rest_mask) != 0 )
+                return false;
+        }
+
+    return true;
+    }
+
+
+    /*!
+        this method rounds to the nearest integer value
+        (it returns a carry if it was)
+
+        for example:
+            2.3 = 2
+            2.8 = 3
+
+            -2.3 = -2
+            -2.8 = 3
+    */
+    uint Round()
+    {
+    Big<exp,man> half;
+    uint c;
+
+        if( IsNan() )
+            return 1;
+
+        if( IsZero() )
+            return 0;
+
+        half.Set05();
+
+        if( IsSign() )
+        {
+            // 'this' is < 0
+            c = Sub( half );
+        }
+        else
+        {
+            // 'this' is > 0
+            c = Add( half );
+        }
+
+        SkipFraction();
+
+    return CheckCarry(c);
+    }
+
+
+
+    /*!
+    *
+    *   input/output operators for standard streams
+    *
+    */
+
+private:
+
+    /*!
+        an auxiliary method for outputing to standard streams
+    */
+    template<class ostream_type, class string_type>
+    static ostream_type & OutputToStream(ostream_type & s, const Big<exp,man> & l)
+    {
+    string_type ss;
+
+        l.ToString(ss);
+        s << ss;
+
+    return s;
+    }
+
+
+public:
+
+
+    /*!
+        output to standard streams
+    */
+    friend std::ostream & operator<<(std::ostream & s,  const Big<exp,man> & l)
+    {
+        return OutputToStream<std::ostream, std::string>(s, l);
+    }
+
+
+
+
+private:
+
+    /*!
+        an auxiliary method for converting from a string
+    */
+    template<class istream_type, class string_type, class char_type>
+    static istream_type & InputFromStream(istream_type & s, Big<exp,man> & l)
+    {
+    string_type ss;
+
+    // char or wchar_t for operator>>
+    char_type z, old_z;
+    bool was_comma = false;
+    bool was_e     = false;
+
+
+        // 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)
+        }
+
+        old_z = 0;
+
+        // we're reading only digits (base=10) and only one comma operator
+        for( ; s.good() ; z=static_cast<char_type>(s.get()) )
+        {
+            if( z=='.' ||  z==',' )
+            {
+                if( was_comma || was_e )
+                    // second comma operator or comma operator after 'e' character
+                    break;
+
+                was_comma = true;
+            }
+            else
+            if( z == 'e' || z == 'E' )
+            {
+                if( was_e )
+                    // second 'e' character
+                    break;
+
+                was_e = true;
+            }
+            else
+            if( z == '+' || z == '-' )
+            {
+                if( old_z != 'e' && old_z != 'E' )
+                    // '+' or '-' is allowed only after 'e' character
+                    break;
+            }
+            else
+            if( Misc::CharToDigit(z, 10) < 0 )
+                break;
+
+
+            ss   += z;
+            old_z = z;
+        }
+
+        // we're leaving the last read character
+        // (it's not belonging to the value)
+        s.unget();
+
+        l.FromString( ss );
+
+    return s;
+    }
+
+
+
+public:
+
+    /*!
+        input from standard streams
+    */
+    friend std::istream & operator>>(std::istream & s, Big<exp,man> & l)
+    {
+        return InputFromStream<std::istream, std::string, char>(s, l);
+    }
+
+
+
+};
+
+
+} // namespace
+
+#endif
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathint.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathint.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,1533 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/*
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathint
+#define headerfilettmathint
+
+/*!
+    \file ttmathint.h
+    \brief template class Int<uint>
+*/
+
+#include "ttmathuint.h"
+
+namespace ttmath
+{
+
+
+/*!
+    \brief Int implements a big integer value with a sign
+
+    value_size - how many bytes specify our value
+        on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
+        on 64bit platforms: value_size=1 -> 8 bytes -> 64 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 SetMax()
+    {
+        UInt<value_size>::SetMax();
+        UInt<value_size>::table[value_size-1] = ~ TTMATH_UINT_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 SetMin()
+    {
+        UInt<value_size>::SetZero();
+        UInt<value_size>::table[value_size-1] = TTMATH_UINT_HIGHEST_BIT;
+    }
+
+
+    /*!
+        this method sets -1 as the value
+        (-1 is equal the max value in an unsigned type)
+    */
+    void SetSignOne()
+    {
+        UInt<value_size>::SetMax();
+    }
+
+
+    /*!
+        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.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)
+
+            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 make a negative value,
+        if the value is negative we do nothing
+    */
+    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 sets an absolute value
+
+        it can return carry (1) (look on ChangeSign() for details)
+    */
+    uint Abs()
+    {
+        if( !IsSign() )
+            return 0;
+
+    return ChangeSign();
+    }
+
+
+
+
+    /*!
+    *
+    *   basic mathematic functions
+    *
+    */
+
+private:
+
+    uint CorrectCarryAfterAdding(bool p1_is_sign, bool p2_is_sign)
+    {
+        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;
+    }
+
+
+public:
+
+    /*!
+        this method adds two value with a sign and returns a 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);
+
+    return CorrectCarryAfterAdding(p1_is_sign, p2_is_sign);
+    }
+
+
+    /*!
+        this method adds one *unsigned* word (at a specific position)
+        and returns a carry (if it was)
+
+        look at a description in UInt<>::AddInt(...)
+    */
+    uint AddInt(uint value, uint index = 0)
+    {
+        bool p1_is_sign = IsSign();
+
+        UInt<value_size>::AddInt(value, index);
+
+    return CorrectCarryAfterAdding(p1_is_sign, false);
+    }
+
+
+    /*!
+        this method adds two *unsigned* words to the existing value
+        and these words begin on the 'index' position
+
+        index should be equal or smaller than value_size-2 (index <= value_size-2)
+        x1 - lower word, x2 - higher word
+
+        look at a description in UInt<>::AddTwoInts(...)
+    */
+    uint AddTwoInts(uint x2, uint x1, uint index)
+    {
+        bool p1_is_sign = IsSign();
+
+        UInt<value_size>::AddTwoInts(x2, x1, index);
+
+    return CorrectCarryAfterAdding(p1_is_sign, false);
+    }
+
+private:
+
+    uint CorrectCarryAfterSubtracting(bool p1_is_sign, bool p2_is_sign)
+    {
+        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;
+    }
+
+public:
+
+    /*!
+        this method subtracts two values with a 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);
+
+    return CorrectCarryAfterSubtracting(p1_is_sign, p2_is_sign);
+    }
+
+
+    /*!
+        this method subtracts one *unsigned* word (at a specific position)
+        and returns a carry (if it was)
+    */
+    uint SubInt(uint value, uint index = 0)
+    {
+        bool p1_is_sign = IsSign();
+
+        UInt<value_size>::SubInt(value, index);
+
+    return CorrectCarryAfterSubtracting(p1_is_sign, false);
+    }
+
+
+    /*!
+        this method adds one to the value and returns carry
+    */
+    uint AddOne()
+    {
+        bool p1_is_sign = IsSign();
+
+        UInt<value_size>::AddOne();
+
+    return CorrectCarryAfterAdding(p1_is_sign, false);
+    }
+
+
+    /*!
+        this method subtracts one from the value and returns carry
+    */
+    uint SubOne()
+    {
+        bool p1_is_sign = IsSign();
+
+        UInt<value_size>::SubOne();
+
+    return CorrectCarryAfterSubtracting(p1_is_sign, false);
+    }
+
+
+
+    /*!
+        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 the 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 different that means if the result
+                is different from that one which has been returned from SetMin()
+                that is carry (result too big) but if the result is equal SetMin()
+                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 SetMin()
+                (this situation is ok)
+            */
+            if( ss1_is_sign != ss2_is_sign )
+            {
+                Int<value_size> temp;
+                temp.SetMin();
+
+                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
+        returned values:
+            0 - ok
+            1 - division by zero
+
+        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) = ss2 * this(new)(result) + remainder
+    */
+    uint Div(Int<value_size> ss2, Int<value_size> * remainder = 0)
+    {
+    bool ss1_is_sign, ss2_is_sign;
+
+        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();
+
+        uint c = UInt<value_size>::Div(ss2, remainder);
+
+        if( ss1_is_sign != ss2_is_sign )
+            SetSign();
+
+        if( ss1_is_sign && remainder )
+            remainder->SetSign();
+
+    return c;
+    }
+
+    uint Div(const Int<value_size> & ss2, Int<value_size> & remainder)
+    {
+        return Div(ss2, &remainder);
+    }
+
+
+    /*!
+        division this = this / ss2  (ss2 is int)
+        returned values:
+            0 - ok
+            1 - division by zero
+
+        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) = ss2 * this(new)(result) + remainder
+    */
+    uint DivInt(sint ss2, sint * remainder = 0)
+    {
+    bool ss1_is_sign, ss2_is_sign;
+
+        ss1_is_sign = IsSign();
+
+        /*
+            we don't have to test the carry from Abs as well as in Mul
+        */
+        Abs();
+
+        if( ss2 < 0 )
+        {
+            ss2 = -ss2;
+            ss2_is_sign = true;
+        }
+        else
+        {
+            ss2_is_sign = false;
+        }
+
+        uint rem;
+        uint c = UInt<value_size>::DivInt((uint)ss2, &rem);
+
+        if( ss1_is_sign != ss2_is_sign )
+            SetSign();
+
+        if( remainder )
+        {
+            if( ss1_is_sign )
+                *remainder = -sint(rem);
+            else
+                *remainder = sint(rem);
+        }
+
+    return c;
+    }
+
+
+    uint DivInt(sint ss2, sint & remainder)
+    {
+        return DivInt(ss2, &remainder);
+    }
+
+
+private:
+
+
+    /*!
+        power this = this ^ pow
+        this can be negative
+        pow is >= 0
+    */
+    uint Pow2(const Int<value_size> & pow)
+    {
+        bool was_sign = IsSign();
+        uint c = 0;
+
+        if( was_sign )
+            c += Abs();
+
+        uint c_temp = UInt<value_size>::Pow(pow);
+        if( c_temp > 0 )
+            return c_temp; // c_temp can be: 0, 1 or 2
+
+        if( was_sign && (pow.table[0] & 1) == 1 )
+            // negative value to the power of odd number is negative
+            c += ChangeSign();
+
+    return (c==0)? 0 : 1;
+    }
+
+
+public:
+
+
+    /*!
+        power this = this ^ pow
+
+        return values:
+        0 - ok
+        1 - carry
+        2 - incorrect arguments 0^0 or 0^(-something)
+    */
+    uint Pow(Int<value_size> pow)
+    {
+        if( !pow.IsSign() )
+            return Pow2(pow);
+
+        if( UInt<value_size>::IsZero() )
+            // if 'pow' is negative then
+            // 'this' must be different from zero
+            return 2;
+
+        if( pow.ChangeSign() )
+            return 1;
+
+        Int<value_size> t(*this);
+        uint c_temp = t.Pow2(pow);
+        if( c_temp > 0 )
+            return c_temp;
+
+        UInt<value_size>::SetOne();
+        if( Div(t) )
+            return 1;
+
+    return 0;
+    }
+
+
+
+    /*!
+    *
+    *   convertion methods
+    *
+    */
+private:
+
+
+    /*!
+        an auxiliary method for converting both from UInt and Int
+    */
+    template<uint argument_size>
+    uint FromUIntOrInt(const UInt<argument_size> & p, bool UInt_type)
+    {
+        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( value_size > argument_size )
+        {
+            uint fill;
+
+            if( UInt_type )
+                fill = 0;
+            else
+                fill = (p.table[argument_size-1] & TTMATH_UINT_HIGHEST_BIT)?
+                                                        TTMATH_UINT_MAX_VALUE : 0;
+
+            // 'this' is longer than 'p'
+            for( ; i<value_size ; ++i)
+                UInt<value_size>::table[i] = fill;
+        }
+        else
+        {
+            uint test = (UInt<value_size>::table[value_size-1] & TTMATH_UINT_HIGHEST_BIT)?
+                                                                TTMATH_UINT_MAX_VALUE : 0;
+
+            if( UInt_type && test!=0 )
+                return 1;
+
+            for( ; i<argument_size ; ++i)
+                if( p.table[i] != test )
+                    return 1;
+        }
+
+    return 0;
+    }
+
+public:
+
+    /*!
+        this method converts an Int<another_size> type into 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)
+    {
+        return FromUIntOrInt(p, false);
+    }
+
+
+    /*!
+        this method converts the sint type into this class
+    */
+    uint FromInt(sint value)
+    {
+    uint fill = ( value<0 ) ? TTMATH_UINT_MAX_VALUE : 0;
+
+        for(uint i=1 ; i<value_size ; ++i)
+            UInt<value_size>::table[i] = fill;
+
+        UInt<value_size>::table[0] = uint(value);
+
+        // there'll never be a carry here
+    return 0;
+    }
+
+
+    /*!
+        this method converts UInt<another_size> into this class
+    */
+    template<uint argument_size>
+    uint FromUInt(const UInt<argument_size> & p)
+    {
+        return FromUIntOrInt(p, true);
+    }
+
+
+    /*!
+        this method converts the uint type into this class
+    */
+    uint FromUInt(uint value)
+    {
+        for(uint i=1 ; i<value_size ; ++i)
+            UInt<value_size>::table[i] = 0;
+
+        UInt<value_size>::table[0] = value;
+
+        // there can be a carry here when the size of this value is equal one word
+        // and the 'value' has the highest bit set
+        if( value_size==1 && (value & TTMATH_UINT_HIGHEST_BIT)!=0 )
+            return 1;
+
+    return 0;
+    }
+
+
+
+    /*!
+        the default assignment operator
+    */
+    Int<value_size> & operator=(const Int<value_size> & p)
+    {
+        FromInt(p);
+
+    return *this;
+    }
+
+
+    /*!
+        this operator converts an Int<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;
+    }
+
+
+    /*!
+        this method converts the sint type to this class
+    */
+    Int<value_size> & operator=(sint i)
+    {
+        FromInt(i);
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting the uint to this class
+    */
+    Int(sint i)
+    {
+        FromInt(i);
+    }
+
+
+    /*!
+        a copy constructor
+    */
+    Int(const Int<value_size> & u)
+    {
+        FromInt(u);
+    }
+
+
+    /*!
+        a constructor for copying from another types
+    */
+    template<uint argument_size>
+    Int(const Int<argument_size> & u)
+    {
+        // look that 'size' we still set as 'value_size' and not as u.value_size
+        FromInt(u);
+    }
+
+
+
+    /*!
+        this operator converts an UInt<another_size> type to this class
+
+        it doesn't return a carry
+    */
+    template<uint argument_size>
+    Int<value_size> & operator=(const UInt<argument_size> & p)
+    {
+        FromUInt(p);
+
+    return *this;
+    }
+
+
+    /*!
+        this method converts the Uint type to this class
+    */
+    Int<value_size> & operator=(uint i)
+    {
+        FromUInt(i);
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting the uint to this class
+    */
+    Int(uint i)
+    {
+        FromUInt(i);
+    }
+
+
+    /*!
+        a constructor for copying from another types
+    */
+    template<uint argument_size>
+    Int(const UInt<argument_size> & u)
+    {
+        // look that 'size' we still set as 'value_size' and not as u.value_size
+        FromUInt(u);
+    }
+
+
+
+
+#ifdef TTMATH_PLATFORM64
+
+    /*!
+        this method converts the signed int type to this class
+
+        ***this operator is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    Int<value_size> & operator=(signed int i)
+    {
+        FromInt(sint(i));
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting the signed int to this class
+
+        ***this constructor is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    Int(signed int i)
+    {
+        FromInt(sint(i));
+    }
+
+
+    /*!
+        this method converts the unsigned int type to this class
+
+        ***this operator is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    Int<value_size> & operator=(unsigned int i)
+    {
+        FromUInt(uint(i));
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting the unsigned int to this class
+
+        ***this constructor is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    Int(unsigned int i)
+    {
+        FromUInt(uint(i));
+    }
+
+#endif
+
+
+    /*!
+        a constructor for converting string to this class (with the base=10)
+    */
+    Int(const char * s)
+    {
+        FromString(s);
+    }
+
+
+    /*!
+        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)
+    */
+    Int(const std::string & s)
+    {
+        FromString( s.c_str() );
+    }
+
+
+    /*!
+        a constructor for converting a string to this class (with the base=10)
+    */
+    Int(const std::wstring & s)
+    {
+        FromString( s.c_str() );
+    }
+
+
+    /*!
+        a default constructor
+
+        we don't clear table etc.
+    */
+    Int()
+    {
+    }
+
+
+    /*!
+        the destructor
+    */
+    ~Int()
+    {
+    }
+
+
+    /*!
+        this method returns the lowest value from table with a sign
+
+        we must be sure when we using this method whether the value
+        will hold in an sint type or not (the rest value from table must be zero or -1)
+    */
+    sint ToInt() const
+    {
+        return sint( UInt<value_size>::table[0] );
+    }
+
+
+private:
+
+    /*!
+        an auxiliary method for converting to a string
+    */
+    template<class string_type>
+    void ToStringBase(string_type & 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);
+        }
+    }
+
+public:
+
+    /*!
+        this method converts the value to a string with a base equal 'b'
+    */
+    void ToString(std::string & result, uint b = 10) const
+    {
+        return ToStringBase(result, b);
+    }
+
+
+    /*!
+        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'
+    */
+    std::string ToString(uint b = 10) const
+    {
+        std::string result;
+        ToStringBase(result, b);
+
+    return result;
+    }
+
+
+    /*!
+        this method converts the value to a string with a base equal 'b'
+    */
+    std::wstring ToWString(uint b = 10) const
+    {
+        std::wstring result;
+        ToStringBase(result, b);
+
+    return result;
+    }
+
+
+private:
+
+    /*!
+        an auxiliary method for converting from a string
+    */
+    template<class char_type>
+    uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
+    {
+    bool is_sign = false;
+
+        Misc::SkipWhiteCharacters(s);
+
+        if( *s == '-' )
+        {
+            is_sign = true;
+            Misc::SkipWhiteCharacters(++s);
+        }
+        else
+        if( *s == '+' )
+        {
+            Misc::SkipWhiteCharacters(++s);
+        }
+
+        if( UInt<value_size>::FromString(s,b,after_source,value_read) )
+            return 1;
+
+        if( is_sign )
+        {
+        Int<value_size> mmin;
+
+            mmin.SetMin();
+
+            /*
+                the reference to mmin will be automatically converted to the reference
+                to UInt type
+                (this value can be equal mmin -- look at a description in ChangeSign())
+            */
+            if( UInt<value_size>::operator>( mmin ) )
+                return 1;
+
+            /*
+                if the value is equal mmin the method ChangeSign() does nothing (only returns 1 but we ignore it)
+            */
+            ChangeSign();
+        }
+        else
+        {
+        Int<value_size> mmax;
+
+            mmax.SetMax();
+
+            if( UInt<value_size>::operator>( mmax ) )
+                    return 1;
+        }
+
+    return 0;
+    }
+
+
+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
+
+        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)
+
+        after_source (if exists) is pointing at the end of the parsed string
+
+        value_read (if exists) tells whether something has actually been read (at least one digit)
+    */
+    uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
+    {
+        return FromStringBase(s, b, after_source, value_read);
+    }
+
+
+    /*!
+        this method converts a string into its value
+    */
+    uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+    {
+        return FromStringBase(s, b, after_source, value_read);
+    }
+
+
+    /*!
+        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(), 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
+    */
+    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)
+    */
+    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 wchar_t * 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;
+    }
+
+
+    /*!
+        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;
+    }
+
+
+    /*!
+    *
+    *   methods for comparing
+    *
+    *
+    */
+
+    bool operator==(const Int<value_size> & l) const
+    {
+        return UInt<value_size>::operator==(l);
+    }
+
+    bool operator!=(const Int<value_size> & l) const
+    {
+        return UInt<value_size>::operator!=(l);
+    }
+
+    bool operator<(const Int<value_size> & l) const
+    {
+        sint i=value_size-1;
+
+        sint a1 = sint(UInt<value_size>::table[i]);
+        sint a2 = sint(l.table[i]);
+
+        if( a1 != a2 )
+            return a1 < a2;
+
+
+        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
+    {
+        sint i=value_size-1;
+
+        sint a1 = sint(UInt<value_size>::table[i]);
+        sint a2 = sint(l.table[i]);
+
+        if( a1 != a2 )
+            return a1 > a2;
+
+
+        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
+    {
+        sint i=value_size-1;
+
+        sint a1 = sint(UInt<value_size>::table[i]);
+        sint a2 = sint(l.table[i]);
+
+        if( a1 != a2 )
+            return a1 < a2;
+
+
+        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
+    {
+        sint i=value_size-1;
+
+        sint a1 = sint(UInt<value_size>::table[i]);
+        sint a2 = sint(l.table[i]);
+
+        if( a1 != a2 )
+            return a1 > a2;
+
+
+        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, remainder);
+
+    return remainder;
+    }
+
+
+    Int<value_size> & operator%=(const Int<value_size> & p2)
+    {
+    Int<value_size> temp(*this);
+    Int<value_size> remainder;
+
+        temp.Div(p2, remainder);
+
+        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--()
+    {
+        SubOne();
+
+    return *this;
+    }
+
+
+    UInt<value_size> operator--(int)
+    {
+    UInt<value_size> temp( *this );
+
+        SubOne();
+
+    return temp;
+    }
+
+
+
+    /*!
+    *
+    *   input/output operators for standard streams
+    *
+    */
+
+private:
+
+    /*!
+        an auxiliary method for outputing to standard streams
+    */
+    template<class ostream_type, class string_type>
+    static ostream_type & OutputToStream(ostream_type & s, const Int<value_size> & l)
+    {
+    string_type ss;
+
+        l.ToString(ss);
+        s << ss;
+
+    return s;
+    }
+
+
+
+public:
+
+
+    /*!
+        output to standard streams
+    */
+    friend std::ostream & operator<<(std::ostream & s, const Int<value_size> & l)
+    {
+        return OutputToStream<std::ostream, std::string>(s, l);
+    }
+
+
+
+
+
+private:
+
+    /*!
+        an auxiliary method for converting from a string
+    */
+    template<class istream_type, class string_type, class char_type>
+    static istream_type & InputFromStream(istream_type & s, Int<value_size> & l)
+    {
+    string_type ss;
+
+    // char or wchar_t for operator>>
+    char_type 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() && Misc::CharToDigit(z, 10)>=0 )
+        {
+            ss += z;
+            z = static_cast<char_type>(s.get());
+        }
+
+        // we're leaving the last readed character
+        // (it's not belonging to the value)
+        s.unget();
+
+        l.FromString(ss);
+
+    return s;
+    }
+
+
+public:
+
+    /*!
+        input from standard streams
+    */
+    friend std::istream & operator>>(std::istream & s, Int<value_size> & l)
+    {
+        return InputFromStream<std::istream, std::string, char>(s, l);
+    }
+
+
+
+};
+
+} // namespace
+
+#endif
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathmisc.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,243 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef headerfilettmathmisc
+#define headerfilettmathmisc
+
+
+/*!
+	\file ttmathmisc.h
+    \brief some helpful functions
+*/
+
+
+#include <string>
+
+
+namespace ttmath
+{
+
+/*!
+	some helpful functions
+*/
+class Misc
+{
+public:
+
+
+/*
+ *
+ *	AssignString(result, str)
+ *	result = str
+ *
+ */
+
+/*!
+	result = str
+*/
+static void AssignString(std::string & result, const char * str)
+{
+	result = str;
+}
+
+
+/*!
+	result = str
+*/
+static void AssignString(std::wstring & result, const char * str)
+{
+	result.clear();
+
+	for( ; *str ; ++str )
+		result += *str;
+}
+
+
+/*!
+	result = str
+*/
+static void AssignString(std::wstring & result, const std::string & str)
+{
+	return AssignString(result, str.c_str());
+}
+
+
+/*!
+	result = str
+*/
+static void AssignString(std::string & result, const wchar_t * str)
+{
+	result.clear();
+
+	for( ; *str ; ++str )
+		result += static_cast<char>(*str);
+}
+
+
+/*!
+	result = str
+*/
+static void AssignString(std::string & result, const std::wstring & str)
+{
+	return AssignString(result, str.c_str());
+}
+
+
+/*
+ *
+ *	AddString(result, str)
+ *	result += str
+ *
+ */
+
+
+/*!
+	result += str
+*/
+static void AddString(std::string & result, const char * str)
+{
+	result += str;
+}
+
+
+/*!
+	result += str
+*/
+static void AddString(std::wstring & result, const char * str)
+{
+	for( ; *str ; ++str )
+		result += *str;
+}
+
+
+
+/*
+	this method omits any white characters from the string
+	char_type is char or wchar_t
+*/
+template<class char_type>
+static void SkipWhiteCharacters(const char_type * & c)
+{
+	// 13 is at the end in a DOS text file (\r\n)
+	while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
+		++c;
+}
+
+
+
+
+/*!
+	this static method converts one character into its value
+
+	for example:
+		1 -> 1
+		8 -> 8
+		A -> 10
+		f -> 15
+
+	this method don't check whether c is correct or not
+*/
+static uint CharToDigit(uint c)
+{
+	if(c>='0' && c<='9')
+		return c-'0';
+
+	if(c>='a' && c<='z')
+		return c-'a'+10;
+
+return c-'A'+10;
+}
+
+
+/*!
+	this method changes a character 'c' into its value
+	(if there can't be a correct value it returns -1)
+
+	for example:
+	c=2, base=10 -> function returns 2
+	c=A, base=10 -> function returns -1
+	c=A, base=16 -> function returns 10
+*/
+static sint CharToDigit(uint c, uint base)
+{
+	if( c>='0' && c<='9' )
+		c=c-'0';
+	else
+	if( c>='a' && c<='z' )
+		c=c-'a'+10;
+	else
+	if( c>='A' && c<='Z' )
+		c=c-'A'+10;
+	else
+		return -1;
+
+
+	if( c >= base )
+		return -1;
+
+
+return sint(c);
+}
+
+
+
+/*!
+	this method converts a digit into a char
+	digit should be from <0,F>
+	(we don't have to get a base)
+	
+	for example:
+		1  -> 1
+		8  -> 8
+		10 -> A
+		15 -> F
+*/
+static uint DigitToChar(uint digit)
+{
+	if( digit < 10 )
+		return digit + '0';
+
+return digit - 10 + 'A';
+}
+
+
+}; // struct Misc
+
+}
+
+
+#endif
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathobjects.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,766 @@
+/*
+ * This file is a part of TTMath Mathematical Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef headerfilettmathobject
+#define headerfilettmathobject
+
+/*!
+	\file ttmathobjects.h
+    \brief Mathematic functions.
+*/
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+
+#include "ttmathtypes.h"
+#include "ttmathmisc.h"
+
+
+namespace ttmath
+{
+
+/*!
+	objects of this class are used with the mathematical parser
+	they hold variables or functions defined by a user
+
+	each object has its own table in which we're keeping variables or functions
+*/
+class Objects
+{
+public:
+
+
+	/*!
+		one item (variable or function)
+		'items' will be on the table
+	*/
+	struct Item
+	{
+		// name of a variable of a function
+		// internally we store variables and funcions as std::string (not std::wstring even when wide characters are used)
+		std::string value;
+
+		// number of parameters required by the function
+		// (if there's a variable this 'param' is ignored)
+		int param;
+
+		Item() {}
+		Item(const std::string & v, int p) : value(v), param(p) {}
+	};
+
+	// 'Table' is the type of our table
+	typedef std::map<std::string, Item> Table;
+	typedef	Table::iterator Iterator;
+	typedef	Table::const_iterator CIterator;
+
+
+
+	/*!
+		this method returns true if a character 'c' is a character
+		which can be in a name
+		
+		if 'can_be_digit' is true that means when the 'c' is a digit this 
+		method returns true otherwise it returns false
+	*/
+	static bool CorrectCharacter(wchar_t c, bool can_be_digit)
+	{
+		if( (c>='a' && c<='z') || (c>='A' && c<='Z') )
+			return true;
+
+		if( can_be_digit && ((c>='0' && c<='9') || c=='_') )
+			return true;
+
+	return false;
+	}
+
+
+	/*!
+		this method returns true if the name can be as a name of an object
+	*/
+	template<class string_type>
+	static bool IsNameCorrect(const string_type & name)
+	{
+		if( name.empty() )
+			return false;
+
+		if( !CorrectCharacter(name[0], false) )
+			return false;
+
+		typename string_type::const_iterator i = name.begin();
+
+		for(++i ; i!=name.end() ; ++i)
+			if( !CorrectCharacter(*i, true) )
+				return false;
+		
+	return true;
+	}
+
+
+	/*!
+		this method returns true if such an object is defined (name exists)
+	*/
+	bool IsDefined(const std::string & name)
+	{
+		Iterator i = table.find(name);
+
+		if( i != table.end() )
+			// we have this object in our table
+			return true;
+
+	return false;
+	}
+
+
+	/*!
+		this method returns true if such an object is defined (name exists)
+	*/
+	bool IsDefined(const std::wstring & name)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(name) )
+			return false;
+
+		Misc::AssignString(str_tmp1, name);
+
+	return IsDefined(str_tmp1);
+	}
+
+
+	/*!
+		this method adds one object (variable of function) into the table
+	*/
+	ErrorCode Add(const std::string & name, const std::string & value, int param = 0)
+	{
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Iterator i = table.find(name);
+
+		if( i != table.end() )
+			// we have this object in our table
+			return err_object_exists;
+
+		table.insert( std::make_pair(name, Item(value, param)) );
+
+	return err_ok;
+	}
+
+
+	/*!
+		this method adds one object (variable of function) into the table
+	*/
+	ErrorCode Add(const std::wstring & name, const std::wstring & value, int param = 0)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Misc::AssignString(str_tmp1, name);
+		Misc::AssignString(str_tmp2, value);
+		
+	return Add(str_tmp1, str_tmp2, param);
+	}
+
+
+	/*!
+		this method returns 'true' if the table is empty
+	*/
+	bool Empty() const
+	{
+		return table.empty();
+	}
+
+
+	/*!
+		this method clears the table
+	*/
+	void Clear()
+	{
+		return table.clear();
+	}
+
+
+	/*!
+		this method returns 'const_iterator' on the first item on the table
+	*/
+	CIterator Begin() const
+	{
+		return table.begin();
+	}
+
+
+	/*!
+		this method returns 'const_iterator' pointing at the space after last item
+		(returns table.end())
+	*/
+	CIterator End() const
+	{
+		return table.end();
+	}
+
+
+	/*!
+		this method changes the value and the number of parameters for a specific object
+	*/
+	ErrorCode EditValue(const std::string & name, const std::string & value, int param = 0)
+	{
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Iterator i = table.find(name);
+
+		if( i == table.end() )
+			return err_unknown_object;
+	
+		i->second.value = value;
+		i->second.param = param;
+
+	return err_ok;
+	}
+
+
+	/*!
+		this method changes the value and the number of parameters for a specific object
+	*/
+	ErrorCode EditValue(const std::wstring & name, const std::wstring & value, int param = 0)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Misc::AssignString(str_tmp1, name);
+		Misc::AssignString(str_tmp2, value);
+		
+	return EditValue(str_tmp1, str_tmp2, param);
+	}
+
+
+	/*!
+		this method changes the name of a specific object
+	*/
+	ErrorCode EditName(const std::string & old_name, const std::string & new_name)
+	{
+		if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
+			return err_incorrect_name;
+
+		Iterator old_i = table.find(old_name);
+		if( old_i == table.end() )
+			return err_unknown_object;
+		
+		if( old_name == new_name )
+			// the new name is the same as the old one
+			// we treat it as a normal situation
+			return err_ok;
+
+		ErrorCode err = Add(new_name, old_i->second.value, old_i->second.param);
+		
+		if( err == err_ok ) 
+		{
+			old_i = table.find(old_name);
+			TTMATH_ASSERT( old_i != table.end() )
+
+			table.erase(old_i);
+		}
+
+	return err;
+	}
+
+
+	/*!
+		this method changes the name of a specific object
+	*/
+	ErrorCode EditName(const std::wstring & old_name, const std::wstring & new_name)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(old_name) || !IsNameCorrect(new_name) )
+			return err_incorrect_name;
+
+		Misc::AssignString(str_tmp1, old_name);
+		Misc::AssignString(str_tmp2, new_name);
+
+	return EditName(str_tmp1, str_tmp2);
+	}
+
+
+	/*!
+		this method deletes an object
+	*/
+	ErrorCode Delete(const std::string & name)
+	{
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Iterator i = table.find(name);
+
+		if( i == table.end() )
+			return err_unknown_object;
+
+		table.erase( i );
+
+	return err_ok;
+	}
+
+
+	/*!
+		this method deletes an object
+	*/
+	ErrorCode Delete(const std::wstring & name)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Misc::AssignString(str_tmp1, name);
+
+	return Delete(str_tmp1);
+	}	
+		
+		
+	/*!
+		this method gets the value of a specific object
+	*/
+	ErrorCode GetValue(const std::string & name, std::string & value) const
+	{
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		CIterator i = table.find(name);
+
+		if( i == table.end() )
+		{
+			value.clear();
+			return err_unknown_object;
+		}
+
+		value = i->second.value;
+
+	return err_ok;
+	}
+
+
+	/*!
+		this method gets the value of a specific object
+	*/
+	ErrorCode GetValue(const std::wstring & name, std::wstring & value)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Misc::AssignString(str_tmp1, name);
+		ErrorCode err = GetValue(str_tmp1, str_tmp2);
+		Misc::AssignString(value, str_tmp2);
+
+	return err;
+	}
+
+
+	/*!
+		this method gets the value of a specific object
+		(this version is used for not copying the whole string)
+	*/
+	ErrorCode GetValue(const std::string & name, const char ** value) const
+	{
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		CIterator i = table.find(name);
+
+		if( i == table.end() )
+		{
+			*value = 0;
+			return err_unknown_object;
+		}
+
+		*value = i->second.value.c_str();
+
+	return err_ok;
+	}
+
+
+	/*!
+		this method gets the value of a specific object
+		(this version is used for not copying the whole string)
+	*/
+	ErrorCode GetValue(const std::wstring & name, const char ** value)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Misc::AssignString(str_tmp1, name);
+
+	return GetValue(str_tmp1, value);
+	}
+
+
+	/*!
+		this method gets the value and the number of parameters
+		of a specific object
+	*/
+	ErrorCode GetValueAndParam(const std::string & name, std::string & value, int * param) const
+	{
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		CIterator i = table.find(name);
+
+		if( i == table.end() )
+		{
+			value.empty();
+			*param = 0;
+			return err_unknown_object;
+		}
+
+		value = i->second.value;
+		*param = i->second.param;
+
+	return err_ok;
+	}
+
+
+	/*!
+		this method gets the value and the number of parameters
+		of a specific object
+	*/
+	ErrorCode GetValueAndParam(const std::wstring & name, std::wstring & value, int * param)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Misc::AssignString(str_tmp1, name);
+		ErrorCode err = GetValueAndParam(str_tmp1, str_tmp2, param);
+		Misc::AssignString(value, str_tmp2);
+
+	return err;
+	}
+
+
+	/*!
+		this method sets the value and the number of parameters
+		of a specific object
+		(this version is used for not copying the whole string)
+	*/
+	ErrorCode GetValueAndParam(const std::string & name, const char ** value, int * param) const
+	{
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		CIterator i = table.find(name);
+
+		if( i == table.end() )
+		{
+			*value = 0;
+			*param = 0;
+			return err_unknown_object;
+		}
+
+		*value = i->second.value.c_str();
+		*param = i->second.param;
+
+	return err_ok;
+	}
+
+
+	/*!
+		this method sets the value and the number of parameters
+		of a specific object
+		(this version is used for not copying the whole string
+		but in fact we make one copying during AssignString())
+	*/
+	ErrorCode GetValueAndParam(const std::wstring & name, const char ** value, int * param)
+	{
+		// we should check whether the name (in wide characters) are correct
+		// before calling AssignString() function
+		if( !IsNameCorrect(name) )
+			return err_incorrect_name;
+
+		Misc::AssignString(str_tmp1, name);
+
+	return GetValueAndParam(str_tmp1, value, param);
+	}
+
+
+	/*!
+		this method returns a pointer into the table
+	*/
+	Table * GetTable()
+	{
+		return &table;
+	}
+
+
+private:
+
+	Table table;
+	std::string str_tmp1, str_tmp2;
+
+}; // end of class Objects
+
+
+
+
+
+
+
+/*!
+	objects of the class History are used to keep values in functions
+	which take a lot of time during calculating, for instance in the 
+	function Factorial(x)
+
+	it means that when we're calculating e.g. Factorial(1000) and the 
+	Factorial finds that we have calculated it before, the value (result)
+	is taken from the history
+*/
+template<class ValueType>
+class History
+{
+	/*!
+		one item in the History's object holds a key, a value for the key
+		and a corresponding error code
+	*/
+	struct Item
+	{
+		ValueType key, value;
+		ErrorCode err;
+	};
+
+
+	/*!
+		we use std::list for simply deleting the first item
+		but because we're searching through the whole container
+		(in the method Get) the container should not be too big
+		(linear time of searching)
+	*/
+	typedef std::list<Item> buffer_type;
+	buffer_type buffer;
+	typename buffer_type::size_type buffer_max_size;
+
+public:
+	
+	/*!
+		default constructor
+		default max size of the History's container is 15 items
+	*/
+	History()
+	{
+		buffer_max_size = 15;
+	}
+
+
+	/*!
+		a constructor which takes another value of the max size
+		of the History's container
+	*/
+	History(typename buffer_type::size_type new_size)
+	{
+		buffer_max_size = new_size;
+	}
+
+
+	/*!
+		this method adds one item into the History
+		if the size of the container is greater than buffer_max_size
+		the first item will be removed
+	*/
+	void Add(const ValueType & key, const ValueType & value, ErrorCode err)
+	{
+		Item item;
+		item.key   = key;
+		item.value = value;
+		item.err   = err;
+
+		buffer.insert( buffer.end(), item );
+
+		if( buffer.size() > buffer_max_size )
+			buffer.erase(buffer.begin());
+	}
+
+
+	/*!
+		this method checks whether we have an item which has the key equal 'key'
+
+		if there's such item the method sets the 'value' and the 'err'
+		and returns true otherwise it returns false and 'value' and 'err'
+		remain unchanged
+	*/
+	bool Get(const ValueType & key, ValueType & value, ErrorCode & err)
+	{
+		typename buffer_type::iterator i = buffer.begin();
+
+		for( ; i != buffer.end() ; ++i )
+		{
+			if( i->key == key )
+			{
+				value = i->value;
+				err   = i->err;
+				return true;
+			}
+		}
+
+	return false;
+	}
+
+
+	/*!
+		this methods deletes an item
+
+		we assume that there is only one item with the 'key'
+		(this methods removes the first one)
+	*/
+	bool Remove(const ValueType & key)
+	{
+		typename buffer_type::iterator i = buffer.begin();
+
+		for( ; i != buffer.end() ; ++i )
+		{
+			if( i->key == key )
+			{
+				buffer.erase(i);
+				return true;
+			}
+		}
+
+	return false;
+	}
+
+
+}; // end of class History
+
+
+
+/*!
+	this is an auxiliary class used when calculating Gamma() or Factorial()
+
+	in multithreaded environment you can provide an object of this class to
+	the Gamma() or Factorial() function, e.g;
+		typedef Big<1, 3> MyBig;
+		MyBig x = 123456;
+		CGamma<MyBig> cgamma;
+		std::cout << Gamma(x, cgamma);
+	each thread should have its own CGamma<> object
+
+	in a single-thread environment a CGamma<> object is a static variable
+	in a second version of Gamma() and you don't have to explicitly use it, e.g.
+		typedef Big<1, 3> MyBig;
+		MyBig x = 123456;
+		std::cout << Gamma(x);
+*/
+template<class ValueType>
+struct CGamma
+{
+	/*!
+		this table holds factorials
+			1
+			1
+			2
+			6
+			24
+			120
+			720
+			.......
+	*/
+	std::vector<ValueType> fact;
+
+
+	/*!
+		this table holds Bernoulli numbers
+			1
+			-0.5
+			0.166666666666666666666666667
+			0
+			-0.0333333333333333333333333333
+			0
+			0.0238095238095238095238095238
+			0
+			-0.0333333333333333333333333333
+			0
+			0.075757575757575757575757576
+			.....
+	*/
+	std::vector<ValueType> bern;
+
+
+	/*!
+		here we store some calculated values
+		(this is for speeding up, if the next argument of Gamma() or Factorial()
+		is in the 'history' then the result we are not calculating but simply
+		return from the 'history' object)
+	*/
+	History<ValueType> history;
+
+
+	/*!
+		this method prepares some coefficients: factorials and Bernoulli numbers
+		stored in 'fact' and 'bern' objects
+		
+		how many values should be depends on the size of the mantissa - if
+		the mantissa is larger then we must calculate more values
+		    for a mantissa which consists of 256 bits (8 words on a 32bit platform)
+			we have to calculate about 30 values (the size of fact and bern will be 30),
+			and for a 2048 bits mantissa we have to calculate 306 coefficients
+
+		you don't have to call this method, these coefficients will be automatically calculated
+		when they are needed
+
+		you must note that calculating these coefficients is a little time-consuming operation,
+		(especially when the mantissa is large) and first call to Gamma() or Factorial()
+		can take more time than next calls, and in the end this is the point when InitAll()
+		comes in handy: you can call this method somewhere at the beginning of your program
+	*/
+	void InitAll();
+	// definition is in ttmath.h
+};
+
+
+
+
+} // namespace
+
+#endif
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathparser.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathparser.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,2754 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathparser
+#define headerfilettmathparser
+
+/*!
+	\file ttmathparser.h
+    \brief A mathematical parser
+*/
+
+#include <cstdio>
+#include <vector>
+#include <map>
+#include <set>
+
+#include "ttmath.h"
+#include "ttmathobjects.h"
+#include "ttmathmisc.h"
+
+
+
+namespace ttmath
+{
+
+/*! 
+	\brief Mathematical parser
+
+	let x will be an input string meaning an expression for converting:
+	
+	x = [+|-]Value[operator[+|-]Value][operator[+|-]Value]...
+	where:
+		an operator can be:
+			^ (pow)   (the heighest priority)
+
+			* (mul)   (or multiplication without an operator -- short mul)
+			/ (div)   (* and / have the same priority)
+
+			+ (add)
+			- (sub)   (+ and - have the same priority)
+
+			< (lower than)
+			> (greater than)
+			<= (lower or equal than)
+			>= (greater or equal than)
+			== (equal)
+			!= (not equal)   (all above logical operators have the same priority)
+			
+			&& (logical and)
+
+			|| (logical or) (the lowest priority)
+
+		short mul:
+ 		 if the second Value (Var below) is either a variable or function there might not be 
+		 an operator between them, e.g.
+	        "[+|-]Value Var" is treated as "[+|-]Value * Var" and the multiplication
+	        has the same priority as a normal multiplication:
+			4x       = 4 * x
+			2^3m     = (2^3)* m
+			6h^3     = 6 * (h^3)
+	        2sin(pi) = 2 * sin(pi)
+			etc.
+
+		Value can be:
+			constant e.g. 100, can be preceded by operators for changing the base (radix): [#|&]
+			                   # - hex
+							   & - bin
+							   sample: #10  = 16
+							           &10  = 2
+			variable e.g. pi
+			another expression between brackets e.g (x)
+			function e.g. sin(x)
+
+	for example a correct input string can be:
+		"1"
+		"2.1234"
+		"2,1234"    (they are the same, by default we can either use a comma or a dot)
+		"1 + 2"
+		"(1 + 2) * 3"
+		"pi"
+		"sin(pi)"
+		"(1+2)*(2+3)"
+		"log(2;1234)"    there's a semicolon here (not a comma), we use it in functions
+		                 for separating parameters
+	    "1 < 2"  (the result will be: 1)
+	    "4 < 3"  (the result will be: 0)
+		"2+x"    (of course if the variable 'x' is defined)
+		"4x+10"
+		"#20+10"     = 32 + 10 = 42
+		"10 ^ -&101" = 10 ^ -5 = 0.00001
+		"8 * -&10"   = 8 * -2  = -16
+		etc.
+
+	we can also use a semicolon for separating any 'x' input strings
+	for example:
+		"1+2;4+5"
+	the result will be on the stack as follows:
+		"3"
+		"9"
+*/
+template<class ValueType>
+class Parser
+{
+private:
+
+/*!
+	there are 5 mathematical operators as follows (with their standard priorities):
+		add (+)
+		sub (-)
+		mul (*)
+		div (/)
+		pow (^)
+		and 'shortmul' used when there is no any operators between
+		a first parameter and a variable or function
+		(the 'shortmul' has the same priority as the normal multiplication )
+*/
+	class MatOperator
+	{
+	public:
+
+		enum Type
+		{
+			none,add,sub,mul,div,pow,lt,gt,let,get,eq,neq,lor,land,shortmul
+		};
+
+		enum Assoc
+		{
+			right,		// right-associative
+			non_right	// associative or left-associative
+		};
+
+		Type  GetType()     const { return type; }
+		int   GetPriority() const { return priority; }
+		Assoc GetAssoc()    const { return assoc; }
+
+		void SetType(Type t)
+		{
+			type  = t;
+			assoc = non_right;
+
+			switch( type )
+			{		
+			case lor:
+				priority = 4;
+				break;
+
+			case land:
+				priority = 5;
+				break;
+
+			case eq:
+			case neq:
+			case lt:
+			case gt:
+			case let:
+			case get:
+				priority = 7;
+				break;
+
+			case add:
+			case sub:
+				priority = 10;
+				break;
+
+			case mul:
+			case shortmul:
+			case div:
+				priority = 12;
+				break;
+
+			case pow:
+				priority = 14;
+				assoc    = right;
+				break;
+
+			default:
+				Error( err_internal_error );
+				break;
+			}
+		}
+
+		MatOperator(): type(none), priority(0), assoc(non_right)
+		{
+		}
+
+	private:
+
+		Type  type;
+		int   priority;
+		Assoc assoc;
+	}; // end of MatOperator class
+
+
+
+public:
+
+
+
+	/*!
+		Objects of type 'Item' we are keeping on our stack
+	*/
+	struct Item
+	{
+		enum Type
+		{
+			none, numerical_value, mat_operator, first_bracket,
+			last_bracket, variable, semicolon
+		};
+
+		// The kind of type which we're keeping
+		Type type;
+
+		// if type == numerical_value
+		ValueType value;
+
+		// if type == mat_operator
+		MatOperator moperator;
+
+		/*
+			if type == first_bracket
+
+			if 'function' is set to true it means that the first recognized bracket
+			was the bracket from function in other words we must call a function when
+			we'll find the 'last' bracket
+		*/
+		bool function;
+
+		// if function is true
+		std::string function_name;
+
+		/*
+			the sign of value
+
+			it can be for type==numerical_value or type==first_bracket
+			when it's true it means e.g. that value is equal -value
+		*/
+		bool sign;
+
+		Item(): type(none), function(false), sign(false)
+		{
+		}
+
+	}; // end of Item struct
+
+
+/*!
+	stack on which we're keeping the Items
+
+	at the end of parsing we'll have the result on its
+	the result don't have to be one value, it can be a list
+	of values separated by the 'semicolon item'
+*/
+std::vector<Item> stack;
+
+
+private:
+
+
+/*!
+	size of the stack when we're starting parsing of the string
+
+	if it's to small while parsing the stack will be automatically resized
+*/
+const int default_stack_size;
+
+
+
+/*!
+	index of an object in our stack
+	it's pointing on the place behind the last element
+	for example at the beginning of parsing its value is zero
+*/
+unsigned int stack_index;
+
+
+/*!
+	code of the last error
+*/
+ErrorCode error;
+
+
+/*!
+	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
+*/
+const char * pstring;
+
+
+/*!
+	the base (radix) of the mathematic system (for example it may be '10')
+*/
+int base;
+
+
+/*!
+	the unit of angles used in: sin,cos,tan,cot,asin,acos,atan,acot
+	0 - deg
+	1 - rad (default)
+	2 - grad
+*/
+int deg_rad_grad;
+
+
+
+/*!
+	a pointer to an object which tell us whether we should stop calculating or not
+*/
+const volatile StopCalculating * pstop_calculating;
+
+
+
+/*!
+	a pointer to the user-defined variables' table
+*/
+const Objects * puser_variables;
+
+/*!
+	a pointer to the user-defined functions' table
+*/
+const Objects * puser_functions;
+
+
+typedef std::map<std::string, ValueType> FunctionLocalVariables;
+
+/*!
+	a pointer to the local variables of a function
+*/
+const FunctionLocalVariables * pfunction_local_variables;
+
+
+/*!
+	a temporary set using during parsing user defined variables
+*/
+std::set<std::string> visited_variables;
+
+
+/*!
+	a temporary set using during parsing user defined functions
+*/
+std::set<std::string> visited_functions;
+
+
+
+
+/*!
+	pfunction is the type of pointer to a mathematic function
+
+	these mathematic functions are private members of this class,
+	they are the wrappers for standard mathematics function
+
+	'pstack' is the pointer to the first argument on our stack
+	'amount_of_arg' tell us how many argument there are in our stack
+	'result' is the reference for result of function 
+*/
+typedef void (Parser<ValueType>::*pfunction)(int pstack, int amount_of_arg, ValueType & result);
+
+
+/*!
+	pfunction is the type of pointer to a method which returns value of variable
+*/
+typedef void (ValueType::*pfunction_var)();
+
+
+/*!
+	table of mathematic functions
+
+	this map consists of:
+		std::string - function's name
+		pfunction - pointer to specific function
+*/
+typedef std::map<std::string, pfunction> FunctionsTable;
+FunctionsTable functions_table;
+
+
+/*!
+	table of mathematic operators
+
+	this map consists of:
+		std::string - operators's name
+		MatOperator::Type - type of the operator
+*/
+typedef std::map<std::string, typename MatOperator::Type> OperatorsTable;
+OperatorsTable operators_table;
+
+
+/*!
+	table of mathematic variables
+
+	this map consists of:
+		std::string     - variable's name
+		pfunction_var - pointer to specific function which returns value of variable
+*/
+typedef std::map<std::string, pfunction_var> VariablesTable;
+VariablesTable variables_table;
+
+
+/*!
+	some coefficients used when calculating the gamma (or factorial) function
+*/
+CGamma<ValueType> cgamma;
+
+
+/*!
+	temporary object for a whole string when Parse(std::wstring) is used
+*/
+std::string wide_to_ansi;
+
+
+/*!
+	group character (used when parsing)
+	default zero (not used)
+*/
+int group;
+
+
+/*!
+	characters used as a comma
+	default: '.' and ','
+	comma2 can be zero (it means it is not used)
+*/
+int comma, comma2;
+
+
+/*!
+	an additional character used as a separator between function parameters
+	(semicolon is used always)
+*/
+int param_sep;
+
+
+/*!
+	true if something was calculated (at least one mathematical operator was used or a function or a variable)
+*/
+bool calculated;
+
+
+
+/*!
+	we're using this method for reporting an error
+*/
+static void Error(ErrorCode code)
+{
+	throw code;
+}
+
+
+/*!
+	this method skips the white character from the string
+
+	it's moving the 'pstring' to the first no-white character
+*/
+void SkipWhiteCharacters()
+{
+	while( (*pstring==' ' ) || (*pstring=='\t') )
+		++pstring;
+}
+
+
+/*!
+	an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
+*/
+void RecurrenceParsingVariablesOrFunction_CheckStopCondition(bool variable, const std::string & name)
+{
+	if( variable )
+	{
+		if( visited_variables.find(name) != visited_variables.end() )
+			Error( err_variable_loop );
+	}
+	else
+	{
+		if( visited_functions.find(name) != visited_functions.end() )
+			Error( err_functions_loop );
+	}
+}
+
+
+/*!
+	an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
+*/
+void RecurrenceParsingVariablesOrFunction_AddName(bool variable, const std::string & name)
+{
+	if( variable )
+		visited_variables.insert( name );
+	else
+		visited_functions.insert( name );
+}
+
+
+/*!
+	an auxiliary method for RecurrenceParsingVariablesOrFunction(...)
+*/
+void RecurrenceParsingVariablesOrFunction_DeleteName(bool variable, const std::string & name)
+{
+	if( variable )
+		visited_variables.erase( name );
+	else
+		visited_functions.erase( name );
+}
+
+
+/*!
+	this method returns the value of a variable or function
+	by creating a new instance of the mathematical parser 
+	and making the standard parsing algorithm on the given string
+
+	this method is used only during parsing user defined variables or functions
+
+	(there can be a recurrence here therefore we're using 'visited_variables'
+	and 'visited_functions' sets to make a stop condition)
+*/
+ValueType RecurrenceParsingVariablesOrFunction(bool variable, const std::string & name, const char * new_string,
+											   FunctionLocalVariables * local_variables = 0)
+{
+	RecurrenceParsingVariablesOrFunction_CheckStopCondition(variable, name);
+	RecurrenceParsingVariablesOrFunction_AddName(variable, name);
+
+	Parser<ValueType> NewParser(*this);
+	ErrorCode err;
+
+	NewParser.pfunction_local_variables = local_variables;
+
+	try
+	{
+		err = NewParser.Parse(new_string);
+	}
+	catch(...)
+	{
+		RecurrenceParsingVariablesOrFunction_DeleteName(variable, name);
+
+	throw;
+	}
+
+	RecurrenceParsingVariablesOrFunction_DeleteName(variable, name);
+
+	if( err != err_ok )
+		Error( err );
+
+	if( NewParser.stack.size() != 1 )
+		Error( err_must_be_only_one_value );
+
+	if( NewParser.stack[0].type != Item::numerical_value )
+		// I think there shouldn't be this error here
+		Error( err_incorrect_value );
+
+return NewParser.stack[0].value;
+}
+
+
+public:
+
+
+/*!
+	this method returns the user-defined value of a variable
+*/
+bool GetValueOfUserDefinedVariable(const std::string & variable_name,ValueType & result)
+{
+	if( !puser_variables )
+		return false;
+
+	const char * string_value;
+
+	if( puser_variables->GetValue(variable_name, &string_value) != err_ok )
+		return false;
+
+	result = RecurrenceParsingVariablesOrFunction(true, variable_name, string_value);
+	calculated = true;
+
+return true;
+}
+
+
+/*!
+	this method returns the value of a local variable of a function
+*/
+bool GetValueOfFunctionLocalVariable(const std::string & variable_name, ValueType & result)
+{
+	if( !pfunction_local_variables )
+		return false;
+
+	typename FunctionLocalVariables::const_iterator i = pfunction_local_variables->find(variable_name);
+
+	if( i == pfunction_local_variables->end() )
+		return false;
+
+	result = i->second;
+
+return true;
+}
+
+
+/*!
+	this method returns the value of a variable from variables' table
+
+	we make an object of type ValueType then call a method which 
+	sets the correct value in it and finally we'll return the object
+*/
+ValueType GetValueOfVariable(const std::string & variable_name)
+{
+ValueType result;
+
+	if( GetValueOfFunctionLocalVariable(variable_name, result) )
+		return result;
+
+	if( GetValueOfUserDefinedVariable(variable_name, result) )
+		return result;
+
+
+	typename std::map<std::string, pfunction_var>::iterator i =
+													variables_table.find(variable_name);
+
+	if( i == variables_table.end() )
+		Error( err_unknown_variable );
+
+	(result.*(i->second))();
+	calculated = true;
+
+return result;
+}
+
+
+private:
+
+/*!
+	wrappers for mathematic functions
+
+	'sindex' is pointing on the first argument on our stack 
+			 (the second argument has 'sindex+2'
+			 because 'sindex+1' is guaranted for the 'semicolon' operator)
+			 the third artument has of course 'sindex+4' etc.
+
+	'result' will be the result of the function
+
+	(we're using exceptions here for example when function gets an improper argument)
+*/
+
+
+/*!
+	used by: sin,cos,tan,cot
+*/
+ValueType ConvertAngleToRad(const ValueType & input)
+{
+	if( deg_rad_grad == 1 ) // rad
+		return input;
+
+	ValueType result;
+	ErrorCode err;
+
+	if( deg_rad_grad == 0 ) // deg
+		result = ttmath::DegToRad(input, &err);
+	else // grad
+		result = ttmath::GradToRad(input, &err);
+
+	if( err != err_ok )
+		Error( err );
+
+return result;
+}
+
+
+/*!
+	used by: asin,acos,atan,acot
+*/
+ValueType ConvertRadToAngle(const ValueType & input)
+{
+	if( deg_rad_grad == 1 ) // rad
+		return input;
+
+	ValueType result;
+	ErrorCode err;
+
+	if( deg_rad_grad == 0 ) // deg
+		result = ttmath::RadToDeg(input, &err);
+	else // grad
+		result = ttmath::RadToGrad(input, &err);
+
+	if( err != err_ok )
+		Error( err );
+
+return result;
+}
+
+
+void Gamma(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	
+	result = ttmath::Gamma(stack[sindex].value, cgamma, &err, pstop_calculating);
+
+	if(err != err_ok)
+		Error( err );
+}
+
+
+/*!
+	factorial
+	result = 1 * 2 * 3 * 4 * .... * x
+*/
+void Factorial(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+
+	result = ttmath::Factorial(stack[sindex].value, cgamma, &err, pstop_calculating);
+
+	if(err != err_ok)
+		Error( err );
+}
+
+
+void Abs(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	result = ttmath::Abs(stack[sindex].value);
+}
+
+void Sin(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Sin( ConvertAngleToRad(stack[sindex].value), &err );
+
+	if(err != err_ok)
+		Error( err );
+}
+
+void Cos(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Cos( ConvertAngleToRad(stack[sindex].value), &err );
+
+	if(err != err_ok)
+		Error( err );
+}
+
+void Tan(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Tan(ConvertAngleToRad(stack[sindex].value), &err);
+
+	if(err != err_ok)
+		Error( err );
+}
+
+void Cot(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Cot(ConvertAngleToRad(stack[sindex].value), &err);
+
+	if(err != err_ok)
+		Error( err );
+}
+
+void Int(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	result = ttmath::SkipFraction(stack[sindex].value);
+}
+
+
+void Round(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	result = stack[sindex].value;
+
+	if( result.Round() )
+		Error( err_overflow );
+}
+
+
+void Ln(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Ln(stack[sindex].value, &err);
+
+	if(err != err_ok)
+		Error( err );
+}
+
+void Log(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 2 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Log(stack[sindex].value, stack[sindex+2].value, &err);
+
+	if(err != err_ok)
+		Error( err );
+}
+
+void Exp(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Exp(stack[sindex].value, &err);
+
+	if(err != err_ok)
+		Error( err );
+}
+
+
+void Max(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args == 0 )
+	{
+		result.SetMax();
+
+	return;
+	}
+
+	result = stack[sindex].value;
+
+	for(int i=1 ; i<amount_of_args ; ++i)
+	{
+		if( result < stack[sindex + i*2].value )
+			result = stack[sindex + i*2].value;
+	}
+}
+
+
+void Min(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args == 0 )
+	{
+		result.SetMin();
+
+	return;
+	}
+
+	result = stack[sindex].value;
+
+	for(int i=1 ; i<amount_of_args ; ++i)
+	{
+		if( result > stack[sindex + i*2].value )
+			result = stack[sindex + i*2].value;
+	}
+}
+
+
+void ASin(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	ValueType temp = ttmath::ASin(stack[sindex].value, &err);
+
+	if(err != err_ok)
+		Error( err );
+
+	result = ConvertRadToAngle(temp);
+}
+
+
+void ACos(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	ValueType temp = ttmath::ACos(stack[sindex].value, &err);
+
+	if(err != err_ok)
+		Error( err );
+
+	result = ConvertRadToAngle(temp);
+}
+
+
+void ATan(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	result = ConvertRadToAngle(ttmath::ATan(stack[sindex].value));
+}
+
+
+void ACot(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	result = ConvertRadToAngle(ttmath::ACot(stack[sindex].value));
+}
+
+
+void Sgn(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	result = ttmath::Sgn(stack[sindex].value);
+}
+
+
+void Mod(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 2 )
+		Error( err_improper_amount_of_arguments );
+
+	if( stack[sindex+2].value.IsZero() )
+		Error( err_improper_argument );
+
+	result = stack[sindex].value;
+	uint c = result.Mod(stack[sindex+2].value);
+
+	if( c )
+		Error( err_overflow );
+}
+
+
+void If(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 3 )
+		Error( err_improper_amount_of_arguments );
+
+
+	if( !stack[sindex].value.IsZero() )
+		result = stack[sindex+2].value;
+	else
+		result = stack[sindex+4].value;
+}
+
+
+void Or(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args < 2 )
+		Error( err_improper_amount_of_arguments );
+
+	for(int i=0 ; i<amount_of_args ; ++i)
+	{
+		if( !stack[sindex+i*2].value.IsZero() )
+		{
+			result.SetOne();
+			return;
+		}
+	}
+
+	result.SetZero();
+}
+
+
+void And(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args < 2 )
+		Error( err_improper_amount_of_arguments );
+
+	for(int i=0 ; i<amount_of_args ; ++i)
+	{
+		if( stack[sindex+i*2].value.IsZero() )
+		{
+			result.SetZero();
+			return;
+		}
+	}
+
+	result.SetOne();
+}
+
+
+void Not(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+
+	if( stack[sindex].value.IsZero() )
+		result.SetOne();
+	else
+		result.SetZero();
+}
+
+
+void DegToRad(int sindex, int amount_of_args, ValueType & result)
+{
+	ErrorCode err = err_ok;
+
+	if( amount_of_args == 1 )
+	{
+		result = ttmath::DegToRad(stack[sindex].value, &err);
+	}
+	else
+	if( amount_of_args == 3 )
+	{
+		result = ttmath::DegToRad(	stack[sindex].value, stack[sindex+2].value,
+									stack[sindex+4].value, &err);
+	}
+	else
+		Error( err_improper_amount_of_arguments );
+
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void RadToDeg(int sindex, int amount_of_args, ValueType & result)
+{
+	ErrorCode err;
+
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+	
+	result = ttmath::RadToDeg(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void DegToDeg(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 3 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::DegToDeg(	stack[sindex].value, stack[sindex+2].value,
+								stack[sindex+4].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void GradToRad(int sindex, int amount_of_args, ValueType & result)
+{
+	ErrorCode err;
+
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+	
+	result = ttmath::GradToRad(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void RadToGrad(int sindex, int amount_of_args, ValueType & result)
+{
+	ErrorCode err;
+
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+	
+	result = ttmath::RadToGrad(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void DegToGrad(int sindex, int amount_of_args, ValueType & result)
+{
+	ErrorCode err = err_ok;
+
+	if( amount_of_args == 1 )
+	{
+		result = ttmath::DegToGrad(stack[sindex].value, &err);
+	}
+	else
+	if( amount_of_args == 3 )
+	{
+		result = ttmath::DegToGrad(	stack[sindex].value, stack[sindex+2].value,
+									stack[sindex+4].value, &err);
+	}
+	else
+		Error( err_improper_amount_of_arguments );
+
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void GradToDeg(int sindex, int amount_of_args, ValueType & result)
+{
+	ErrorCode err;
+
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+	
+	result = ttmath::GradToDeg(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void Ceil(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Ceil(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void Floor(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Floor(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+void Sqrt(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Sqrt(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void Sinh(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Sinh(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void Cosh(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Cosh(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void Tanh(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Tanh(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void Coth(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Coth(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void Root(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 2 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::Root(stack[sindex].value, stack[sindex+2].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+
+void ASinh(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::ASinh(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void ACosh(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::ACosh(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void ATanh(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::ATanh(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void ACoth(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	ErrorCode err;
+	result = ttmath::ACoth(stack[sindex].value, &err);
+
+	if( err != err_ok )
+		Error( err );
+}
+
+
+void BitAnd(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 2 )
+		Error( err_improper_amount_of_arguments );
+
+	uint err;
+	result = stack[sindex].value;
+	err = result.BitAnd(stack[sindex+2].value);
+
+	switch(err)
+	{
+	case 1:
+		Error( err_overflow );
+		break;
+	case 2:
+		Error( err_improper_argument );
+		break;
+	}
+}
+
+void BitOr(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 2 )
+		Error( err_improper_amount_of_arguments );
+
+	uint err;
+	result = stack[sindex].value;
+	err = result.BitOr(stack[sindex+2].value);
+
+	switch(err)
+	{
+	case 1:
+		Error( err_overflow );
+		break;
+	case 2:
+		Error( err_improper_argument );
+		break;
+	}
+}
+
+
+void BitXor(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 2 )
+		Error( err_improper_amount_of_arguments );
+
+	uint err;
+	result = stack[sindex].value;
+	err = result.BitXor(stack[sindex+2].value);
+
+	switch(err)
+	{
+	case 1:
+		Error( err_overflow );
+		break;
+	case 2:
+		Error( err_improper_argument );
+		break;
+	}
+}
+
+
+void Sum(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args == 0 )
+		Error( err_improper_amount_of_arguments );
+
+	result = stack[sindex].value;
+
+	for(int i=1 ; i<amount_of_args ; ++i )
+		if( result.Add( stack[ sindex + i*2 ].value ) )
+			Error( err_overflow );
+}	
+
+void Avg(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args == 0 )
+		Error( err_improper_amount_of_arguments );
+
+	result = stack[sindex].value;
+
+	for(int i=1 ; i<amount_of_args ; ++i )
+		if( result.Add( stack[ sindex + i*2 ].value ) )
+			Error( err_overflow );
+
+	if( result.Div( amount_of_args ) )
+		Error( err_overflow );
+}	
+
+
+void Frac(int sindex, int amount_of_args, ValueType & result)
+{
+	if( amount_of_args != 1 )
+		Error( err_improper_amount_of_arguments );
+
+	result = stack[sindex].value;
+	result.RemainFraction();
+}
+
+
+
+
+/*!
+	we use such a method because 'wvsprintf' is not everywhere defined
+*/
+void Sprintf(char * buffer, int par)
+{
+char buf[30]; // char, not wchar_t etc.
+int i;
+
+	#ifdef _MSC_VER
+	#pragma warning( disable: 4996 )
+	//warning C4996: 'sprintf': This function or variable may be unsafe.
+	#endif
+
+	sprintf(buf, "%d", par);
+	for(i=0 ; buf[i] != 0 ; ++i)
+		buffer[i] = buf[i];
+
+	buffer[i] = 0;
+
+	#ifdef _MSC_VER
+	#pragma warning( default: 4996 )
+	#endif
+}
+
+
+
+
+/*!
+	this method returns the value from a user-defined function
+
+	(look at the description in 'CallFunction(...)')
+*/
+bool GetValueOfUserDefinedFunction(const std::string & function_name, int amount_of_args, int sindex)
+{
+	if( !puser_functions )
+		return false;
+
+	const char * string_value;
+	int param;
+
+	if( puser_functions->GetValueAndParam(function_name, &string_value, ¶m) != err_ok )
+		return false;
+
+	if( param != amount_of_args )
+		Error( err_improper_amount_of_arguments );
+
+
+	FunctionLocalVariables local_variables;
+
+	if( amount_of_args > 0 )
+	{
+		char buffer[30];
+
+		// x = x1
+		buffer[0] = 'x';
+		buffer[1] = 0;
+		local_variables.insert( std::make_pair(buffer, stack[sindex].value) );
+
+		for(int i=0 ; i<amount_of_args ; ++i)
+		{
+			buffer[0] = 'x';
+			Sprintf(buffer+1, i+1);
+			local_variables.insert( std::make_pair(buffer, stack[sindex + i*2].value) );
+		}
+	}
+
+	stack[sindex-1].value = RecurrenceParsingVariablesOrFunction(false, function_name, string_value, &local_variables);
+	calculated = true;
+
+return true;
+}
+
+
+/*
+	we're calling a specific function
+
+	function_name  - name of the function
+	amount_of_args - how many arguments there are on our stack
+					 (function must check whether this is a correct value or not)
+	sindex         - index of the first argument on the stack (sindex is greater than zero)
+  					 if there aren't any arguments on the stack 'sindex' pointing on
+					 a non existend element (after the first bracket)
+
+	result will be stored in 'stack[sindex-1].value'
+	(we don't have to set the correct type of this element, it'll be set later)
+*/
+void CallFunction(const std::string & function_name, int amount_of_args, int sindex)
+{
+	if( GetValueOfUserDefinedFunction(function_name, amount_of_args, sindex) )
+		return;
+
+	typename FunctionsTable::iterator i = functions_table.find( function_name );
+
+	if( i == functions_table.end() )
+		Error( err_unknown_function );
+
+	/*
+		calling the specify function
+	*/
+	(this->*(i->second))(sindex, amount_of_args, stack[sindex-1].value);
+	calculated = true;
+}
+
+
+
+
+
+/*!
+	inserting a function to the functions' table
+
+	function_name - name of the function
+	pf - pointer to the function (to the wrapper)
+*/
+void InsertFunctionToTable(const char * function_name, pfunction pf)
+{
+	std::string str;
+	Misc::AssignString(str, function_name);
+
+	functions_table.insert( std::make_pair(str, pf) );
+}
+
+
+
+/*!
+	inserting a function to the variables' table
+	(this function returns value of variable)
+
+	variable_name - name of the function
+	pf - pointer to the function
+*/
+void InsertVariableToTable(const char * variable_name, pfunction_var pf)
+{
+	std::string str;
+	Misc::AssignString(str, variable_name);
+
+	variables_table.insert( std::make_pair(str, pf) );
+}
+
+
+/*!
+	this method creates the table of functions
+*/
+void CreateFunctionsTable()
+{
+	InsertFunctionToTable("gamma",		&Parser<ValueType>::Gamma);
+	InsertFunctionToTable("factorial",	&Parser<ValueType>::Factorial);
+	InsertFunctionToTable("abs",   		&Parser<ValueType>::Abs);
+	InsertFunctionToTable("sin",   		&Parser<ValueType>::Sin);
+	InsertFunctionToTable("cos",   		&Parser<ValueType>::Cos);
+	InsertFunctionToTable("tan",   		&Parser<ValueType>::Tan);
+	InsertFunctionToTable("tg",			&Parser<ValueType>::Tan);
+	InsertFunctionToTable("cot",  		&Parser<ValueType>::Cot);
+	InsertFunctionToTable("ctg",  		&Parser<ValueType>::Cot);
+	InsertFunctionToTable("int",	   	&Parser<ValueType>::Int);
+	InsertFunctionToTable("round",	 	&Parser<ValueType>::Round);
+	InsertFunctionToTable("ln",			&Parser<ValueType>::Ln);
+	InsertFunctionToTable("log",	   	&Parser<ValueType>::Log);
+	InsertFunctionToTable("exp",	   	&Parser<ValueType>::Exp);
+	InsertFunctionToTable("max",	   	&Parser<ValueType>::Max);
+	InsertFunctionToTable("min",	   	&Parser<ValueType>::Min);
+	InsertFunctionToTable("asin",   	&Parser<ValueType>::ASin);
+	InsertFunctionToTable("acos",   	&Parser<ValueType>::ACos);
+	InsertFunctionToTable("atan",   	&Parser<ValueType>::ATan);
+	InsertFunctionToTable("atg",	   	&Parser<ValueType>::ATan);
+	InsertFunctionToTable("acot",   	&Parser<ValueType>::ACot);
+	InsertFunctionToTable("actg",   	&Parser<ValueType>::ACot);
+	InsertFunctionToTable("sgn",   		&Parser<ValueType>::Sgn);
+	InsertFunctionToTable("mod",   		&Parser<ValueType>::Mod);
+	InsertFunctionToTable("if",   		&Parser<ValueType>::If);
+	InsertFunctionToTable("or",   		&Parser<ValueType>::Or);
+	InsertFunctionToTable("and",  		&Parser<ValueType>::And);
+	InsertFunctionToTable("not",  		&Parser<ValueType>::Not);
+	InsertFunctionToTable("degtorad",	&Parser<ValueType>::DegToRad);
+	InsertFunctionToTable("radtodeg",	&Parser<ValueType>::RadToDeg);
+	InsertFunctionToTable("degtodeg",	&Parser<ValueType>::DegToDeg);
+	InsertFunctionToTable("gradtorad",	&Parser<ValueType>::GradToRad);
+	InsertFunctionToTable("radtograd",	&Parser<ValueType>::RadToGrad);
+	InsertFunctionToTable("degtograd",	&Parser<ValueType>::DegToGrad);
+	InsertFunctionToTable("gradtodeg",	&Parser<ValueType>::GradToDeg);
+	InsertFunctionToTable("ceil",		&Parser<ValueType>::Ceil);
+	InsertFunctionToTable("floor",		&Parser<ValueType>::Floor);
+	InsertFunctionToTable("sqrt",		&Parser<ValueType>::Sqrt);
+	InsertFunctionToTable("sinh",		&Parser<ValueType>::Sinh);
+	InsertFunctionToTable("cosh",		&Parser<ValueType>::Cosh);
+	InsertFunctionToTable("tanh",		&Parser<ValueType>::Tanh);
+	InsertFunctionToTable("tgh",		&Parser<ValueType>::Tanh);
+	InsertFunctionToTable("coth",		&Parser<ValueType>::Coth);
+	InsertFunctionToTable("ctgh",		&Parser<ValueType>::Coth);
+	InsertFunctionToTable("root",		&Parser<ValueType>::Root);
+	InsertFunctionToTable("asinh",		&Parser<ValueType>::ASinh);
+	InsertFunctionToTable("acosh",		&Parser<ValueType>::ACosh);
+	InsertFunctionToTable("atanh",		&Parser<ValueType>::ATanh);
+	InsertFunctionToTable("atgh",		&Parser<ValueType>::ATanh);
+	InsertFunctionToTable("acoth",		&Parser<ValueType>::ACoth);
+	InsertFunctionToTable("actgh",		&Parser<ValueType>::ACoth);
+	InsertFunctionToTable("bitand",		&Parser<ValueType>::BitAnd);
+	InsertFunctionToTable("bitor",		&Parser<ValueType>::BitOr);
+	InsertFunctionToTable("bitxor",		&Parser<ValueType>::BitXor);
+	InsertFunctionToTable("band",		&Parser<ValueType>::BitAnd);
+	InsertFunctionToTable("bor",		&Parser<ValueType>::BitOr);
+	InsertFunctionToTable("bxor",		&Parser<ValueType>::BitXor);
+	InsertFunctionToTable("sum",		&Parser<ValueType>::Sum);
+	InsertFunctionToTable("avg",		&Parser<ValueType>::Avg);
+	InsertFunctionToTable("frac",		&Parser<ValueType>::Frac);
+}
+
+
+/*!
+	this method creates the table of variables
+*/
+void CreateVariablesTable()
+{
+	InsertVariableToTable("pi", &ValueType::SetPi);
+	InsertVariableToTable("e",  &ValueType::SetE);
+}
+
+
+/*!
+	converting from a big letter to a small one
+*/
+int ToLowerCase(int c)
+{
+	if( c>='A' && c<='Z' )
+		return c - 'A' + 'a';
+
+return c;
+}
+
+
+/*!
+	this method read the name of a variable or a function
+	
+		'result' will be the name of a variable or a function
+		function return 'false' if this name is the name of a variable
+		or function return 'true' if this name is the name of a function
+
+	what should be returned is tested just by a '(' character that means if there's
+	a '(' character after a name that function returns 'true'
+*/
+bool ReadName(std::string & result)
+{
+int character;
+
+
+	result.erase();
+	character = *pstring;
+
+	/*
+		the first letter must be from range 'a' - 'z' or 'A' - 'Z'
+	*/
+	if( ! (( character>='a' && character<='z' ) || ( character>='A' && character<='Z' )) )
+		Error( err_unknown_character );
+
+
+	do
+	{
+		result   += static_cast<char>( character );
+		character = * ++pstring;
+	}
+	while(	(character>='a' && character<='z') ||
+			(character>='A' && character<='Z') ||
+			(character>='0' && character<='9') ||
+			character=='_' );
+	
+
+	SkipWhiteCharacters();
+	
+
+	/*
+		if there's a character '(' that means this name is a name of a function
+	*/
+	if( *pstring == '(' )
+	{
+		++pstring;
+		return true;
+	}
+	
+	
+return false;
+}
+
+
+/*!
+	we're checking whether the first character is '-' or '+'
+	if it is we'll return 'true' and if it is equally '-' we'll set the 'sign' member of 'result'
+*/
+bool TestSign(Item & result)
+{
+	SkipWhiteCharacters();
+	result.sign = false;
+
+	if( *pstring == '-' || *pstring == '+' )
+	{
+		if( *pstring == '-' )
+			result.sign = true;
+
+		++pstring;
+
+	return true;
+	}
+
+return false;
+}
+
+
+/*!
+	we're reading the name of a variable or a function
+	if is there a function we'll return 'true'
+*/
+bool ReadVariableOrFunction(Item & result)
+{
+std::string name;
+bool is_it_name_of_function = ReadName(name);
+
+	if( is_it_name_of_function )
+	{
+		/*
+			we've read the name of a function
+		*/
+		result.function_name = name;
+		result.type     = Item::first_bracket;
+		result.function = true;
+	}
+	else
+	{
+		/*
+			we've read the name of a variable and we're getting its value now
+		*/
+		result.value = GetValueOfVariable( name );
+	}
+
+return is_it_name_of_function;
+}
+
+
+
+
+/*!
+	we're reading a numerical value directly from the string
+*/
+void ReadValue(Item & result, int reading_base)
+{
+const char * new_stack_pointer;
+bool value_read;
+Conv conv;
+
+	conv.base   = reading_base;
+	conv.comma  = comma;
+	conv.comma2 = comma2;
+	conv.group  = group;
+
+	uint carry = result.value.FromString(pstring, conv, &new_stack_pointer, &value_read);
+	pstring    = new_stack_pointer;
+
+	if( carry )
+		Error( err_overflow );
+
+	if( !value_read )
+		Error( err_unknown_character );
+}
+
+
+/*!
+	this method returns true if 'character' is a proper first digit for the value (or a comma -- can be first too)
+*/
+bool ValueStarts(int character, int base)
+{
+	if( character == comma )
+		return true;
+
+	if( comma2!=0 && character==comma2 )
+		return true;
+
+	if( Misc::CharToDigit(character, base) != -1 )
+		return true;
+
+return false;
+}
+
+
+/*!
+	we're reading the item
+  
+	return values:
+		0 - all ok, the item is successfully read
+		1 - the end of the string (the item is not read)
+		2 - the final bracket ')'
+*/
+int ReadValueVariableOrFunction(Item & result)
+{
+bool it_was_sign = false;
+int  character;
+
+
+	if( TestSign(result) )
+		// 'result.sign' was set as well
+		it_was_sign = true;
+
+	SkipWhiteCharacters();
+	character = ToLowerCase( *pstring );
+
+
+	if( character == 0 )
+	{
+		if( it_was_sign )
+			// at the end of the string a character like '-' or '+' has left
+			Error( err_unexpected_end );
+
+		// there's the end of the string here
+		return 1;
+	}
+	else
+	if( character == '(' )
+	{
+		// we've got a normal bracket (not a function)
+		result.type = Item::first_bracket;
+		result.function = false;
+		++pstring;
+
+	return 0;
+	}
+	else
+	if( character == ')' )
+	{
+		// we've got a final bracket
+		// (in this place we can find a final bracket only when there are empty brackets
+		// without any values inside or with a sign '-' or '+' inside)
+
+		if( it_was_sign )
+			Error( err_unexpected_final_bracket );
+
+		result.type = Item::last_bracket;
+
+		// we don't increment 'pstring', this final bracket will be read next by the 
+		// 'ReadOperatorAndCheckFinalBracket(...)' method
+
+	return 2;
+	}
+	else
+	if( character == '#' )
+	{
+		++pstring;
+		SkipWhiteCharacters();
+
+		// after '#' character we do not allow '-' or '+' (can be white characters)
+		if(	ValueStarts(*pstring, 16) )
+			ReadValue( result, 16 );
+		else
+			Error( err_unknown_character );
+	}
+	else
+	if( character == '&' )
+	{
+		++pstring;
+		SkipWhiteCharacters();
+
+		// after '&' character we do not allow '-' or '+' (can be white characters)
+		if(	ValueStarts(*pstring, 2) )
+			ReadValue( result, 2 );
+		else
+			Error( err_unknown_character );
+	}
+	else
+	if(	ValueStarts(character, base) )
+	{
+		ReadValue( result, base );
+	}
+	else
+	if( character>='a' && character<='z' )
+	{
+		if( ReadVariableOrFunction(result) )
+			// we've read the name of a function
+			return 0;
+	}
+	else
+		Error( err_unknown_character );
+
+
+
+	/*
+		we've got a value in the 'result'
+		this value is from a variable or directly from the string
+	*/
+	result.type = Item::numerical_value;
+	
+	if( result.sign )
+	{
+		result.value.ChangeSign();
+		result.sign = false;
+	}
+	
+
+return 0;
+}
+
+
+void InsertOperatorToTable(const char * name, typename MatOperator::Type type)
+{
+	operators_table.insert( std::make_pair(std::string(name), type) );
+}
+
+
+/*!
+	this method creates the table of operators
+*/
+void CreateMathematicalOperatorsTable()
+{
+	InsertOperatorToTable("||", MatOperator::lor);
+	InsertOperatorToTable("&&", MatOperator::land);
+	InsertOperatorToTable("!=", MatOperator::neq);
+	InsertOperatorToTable("==", MatOperator::eq);
+	InsertOperatorToTable(">=", MatOperator::get);
+	InsertOperatorToTable("<=", MatOperator::let);
+	InsertOperatorToTable(">",  MatOperator::gt);
+	InsertOperatorToTable("<",  MatOperator::lt);
+	InsertOperatorToTable("-",  MatOperator::sub);
+	InsertOperatorToTable("+",  MatOperator::add);
+	InsertOperatorToTable("/",  MatOperator::div);
+	InsertOperatorToTable("*",  MatOperator::mul);
+	InsertOperatorToTable("^",  MatOperator::pow);
+}
+
+
+/*!
+	returns true if 'str2' is the substring of str1
+
+	e.g.
+	true when str1="test" and str2="te"
+*/
+bool IsSubstring(const std::string & str1, const std::string & str2)
+{
+	if( str2.length() > str1.length() )
+		return false;
+
+	for(typename std::string::size_type i=0 ; i<str2.length() ; ++i)
+		if( str1[i] != str2[i] )
+			return false;
+
+return true;
+}
+
+
+/*!
+	this method reads a mathematical (or logical) operator
+*/
+void ReadMathematicalOperator(Item & result)
+{
+std::string oper;
+typename OperatorsTable::iterator iter_old, iter_new;
+
+	iter_old = operators_table.end();
+
+	for( ; true ; ++pstring )
+	{
+		oper += *pstring;
+		iter_new = operators_table.lower_bound(oper);
+		
+		if( iter_new == operators_table.end() || !IsSubstring(iter_new->first, oper) )
+		{
+			oper.erase( --oper.end() ); // we've got mininum one element
+
+			if( iter_old != operators_table.end() && iter_old->first == oper )
+			{
+				result.type = Item::mat_operator;
+				result.moperator.SetType( iter_old->second );
+				break;
+			}
+			
+			Error( err_unknown_operator );
+		}
+	
+		iter_old = iter_new;
+	}
+}
+
+
+/*!
+	this method makes a calculation for the percentage operator
+	e.g.
+	1000-50% = 1000-(1000*0,5) = 500
+*/
+void OperatorPercentage()
+{
+	if( stack_index < 3										||
+		stack[stack_index-1].type != Item::numerical_value	||
+		stack[stack_index-2].type != Item::mat_operator		||
+		stack[stack_index-3].type != Item::numerical_value	)
+		Error(err_percent_from);
+
+	++pstring;
+	SkipWhiteCharacters();
+
+	uint c = 0;
+	c += stack[stack_index-1].value.Div(100);
+	c += stack[stack_index-1].value.Mul(stack[stack_index-3].value);
+
+	if( c )
+		Error(err_overflow);
+}
+
+
+/*!
+	this method reads a mathematic operators
+	or the final bracket or the semicolon operator
+
+	return values:
+		0 - ok
+		1 - the string is finished
+*/
+int ReadOperator(Item & result)
+{
+	SkipWhiteCharacters();
+
+	if( *pstring == '%' )
+		OperatorPercentage();
+
+
+	if( *pstring == 0 )
+		return 1;
+	else
+	if( *pstring == ')' )
+	{
+		result.type = Item::last_bracket;
+		++pstring;
+	}
+	else
+	if( *pstring == ';' || (param_sep!=0 && *pstring==param_sep) )
+	{
+		result.type = Item::semicolon;
+		++pstring;
+	}
+	else
+	if( (*pstring>='a' && *pstring<='z') || (*pstring>='A' && *pstring<='Z') )
+	{
+		// short mul (without any operators)
+
+		result.type = Item::mat_operator;
+		result.moperator.SetType( MatOperator::shortmul );
+	}
+	else
+		ReadMathematicalOperator(result);
+
+return 0;
+}
+
+
+
+/*!
+	this method is making the standard mathematic operation like '-' '+' '*' '/' and '^'
+
+	the operation is made between 'value1' and 'value2'
+	the result of this operation is stored in the 'value1'
+*/
+void MakeStandardMathematicOperation(ValueType & value1, typename MatOperator::Type mat_operator,
+									const ValueType & value2)
+{
+uint res;
+
+	calculated = true;
+
+	switch( mat_operator )
+	{
+	case MatOperator::land:
+		(!value1.IsZero() && !value2.IsZero()) ? value1.SetOne() : value1.SetZero();
+		break;
+
+	case MatOperator::lor:
+		(!value1.IsZero() || !value2.IsZero()) ? value1.SetOne() : value1.SetZero();
+		break;
+
+	case MatOperator::eq:
+		(value1 == value2) ? value1.SetOne() : value1.SetZero();
+		break;
+
+	case MatOperator::neq:
+		(value1 != value2) ? value1.SetOne() : value1.SetZero();
+		break;
+
+	case MatOperator::lt:
+		(value1 < value2) ? value1.SetOne() : value1.SetZero();
+		break;
+
+	case MatOperator::gt:
+		(value1 > value2) ? value1.SetOne() : value1.SetZero();
+		break;
+
+	case MatOperator::let:
+		(value1 <= value2) ? value1.SetOne() : value1.SetZero();
+		break;
+
+	case MatOperator::get:
+		(value1 >= value2) ? value1.SetOne() : value1.SetZero();
+		break;
+
+	case MatOperator::sub:
+		if( value1.Sub(value2) ) Error( err_overflow );
+		break;
+
+	case MatOperator::add:
+		if( value1.Add(value2) ) Error( err_overflow );
+		break;
+
+	case MatOperator::mul:
+	case MatOperator::shortmul:
+		if( value1.Mul(value2) ) Error( err_overflow );
+		break;
+
+	case MatOperator::div:
+		if( value2.IsZero() )    Error( err_division_by_zero );
+		if( value1.Div(value2) ) Error( err_overflow );
+		break;
+
+	case MatOperator::pow:
+		res = value1.Pow( value2 );
+
+		if( res == 1 ) Error( err_overflow );
+		else
+		if( res == 2 ) Error( err_improper_argument );
+
+		break;
+
+	default:
+		/*
+			on the stack left an unknown operator but we had to recognize its before
+			that means there's an error in our algorithm
+		*/
+		Error( err_internal_error );
+	}
+}
+
+
+
+
+/*!
+	this method is trying to roll the stack up with the operator's priority
+
+	for example if there are:
+		"1 - 2 +" 
+	we can subtract "1-2" and the result store on the place where is '1' and copy the last
+	operator '+', that means there'll be '-1+' on our stack
+
+	but if there are:
+		"1 - 2 *"
+	we can't roll the stack up because the operator '*' has greater priority than '-'
+*/
+void TryRollingUpStackWithOperatorPriority()
+{
+	while(	stack_index>=4 &&
+			stack[stack_index-4].type == Item::numerical_value &&
+			stack[stack_index-3].type == Item::mat_operator    &&
+			stack[stack_index-2].type == Item::numerical_value &&
+			stack[stack_index-1].type == Item::mat_operator    &&
+			(
+				(
+					// the first operator has greater priority
+					stack[stack_index-3].moperator.GetPriority() > stack[stack_index-1].moperator.GetPriority()
+				) ||
+				(
+					// or both operators have the same priority and the first operator is not right associative
+					stack[stack_index-3].moperator.GetPriority() == stack[stack_index-1].moperator.GetPriority() &&
+					stack[stack_index-3].moperator.GetAssoc()    == MatOperator::non_right
+				)
+			)
+		 )
+	{
+		MakeStandardMathematicOperation(stack[stack_index-4].value,
+										stack[stack_index-3].moperator.GetType(),
+										stack[stack_index-2].value);
+
+
+		/*
+			copying the last operator and setting the stack pointer to the correct value
+		*/
+		stack[stack_index-3] = stack[stack_index-1];
+		stack_index -= 2;
+	}
+}
+
+
+/*!
+	this method is trying to roll the stack up without testing any operators
+
+	for example if there are:
+		"1 - 2" 
+	there'll be "-1" on our stack
+*/
+void TryRollingUpStack()
+{
+	while(	stack_index >= 3 &&
+			stack[stack_index-3].type == Item::numerical_value &&
+			stack[stack_index-2].type == Item::mat_operator &&
+			stack[stack_index-1].type == Item::numerical_value )
+	{
+		MakeStandardMathematicOperation(	stack[stack_index-3].value,
+											stack[stack_index-2].moperator.GetType(),
+											stack[stack_index-1].value );
+
+		stack_index -= 2;
+	}
+}
+
+
+/*!
+	this method is reading a value or a variable or a function
+	(the normal first bracket as well) and push it into the stack
+*/
+int ReadValueVariableOrFunctionAndPushItIntoStack(Item & temp)
+{
+int code = ReadValueVariableOrFunction( temp );
+	
+	if( code == 0 )
+	{
+		if( stack_index < stack.size() )
+			stack[stack_index] = temp;
+		else
+			stack.push_back( temp );
+
+		++stack_index;
+	}
+
+	if( code == 2 )
+		// there was a final bracket, we didn't push it into the stack 
+		// (it'll be read by the 'ReadOperatorAndCheckFinalBracket' method next)
+		code = 0;
+
+
+return code;
+}
+
+
+
+/*!
+	this method calculate how many parameters there are on the stack
+	and the index of the first parameter
+
+	if there aren't any parameters on the stack this method returns
+	'size' equals zero and 'index' pointing after the first bracket
+	(on non-existend element)
+*/
+void HowManyParameters(int & size, int & index)
+{
+	size  = 0;
+	index = stack_index;
+
+	if( index == 0 )
+		// we haven't put a first bracket on the stack
+		Error( err_unexpected_final_bracket );
+
+
+	if( stack[index-1].type == Item::first_bracket )
+		// empty brackets
+		return;
+
+	for( --index ; index>=1 ; index-=2 )
+	{
+		if( stack[index].type != Item::numerical_value )
+		{
+			/*
+				this element must be 'numerical_value', if not that means 
+				there's an error in our algorithm
+			*/
+			Error( err_internal_error );
+		}
+
+		++size;
+
+		if( stack[index-1].type != Item::semicolon )
+			break;
+	}
+
+	if( index<1 || stack[index-1].type != Item::first_bracket )
+	{
+		/*
+			we haven't put a first bracket on the stack
+		*/
+		Error( err_unexpected_final_bracket );
+	}
+}
+
+
+/*!
+	this method is being called when the final bracket ')' is being found
+
+	this method's rolling the stack up, counting how many parameters there are
+	on the stack and if there was a function it's calling the function
+*/
+void RollingUpFinalBracket()
+{
+int amount_of_parameters;
+int index;
+
+	
+	if( stack_index<1 ||
+		(stack[stack_index-1].type != Item::numerical_value &&
+		 stack[stack_index-1].type != Item::first_bracket)
+	  )
+		Error( err_unexpected_final_bracket );
+	
+
+	TryRollingUpStack();
+	HowManyParameters(amount_of_parameters, index);
+
+	// 'index' will be greater than zero
+	// 'amount_of_parameters' can be zero
+
+
+	if( amount_of_parameters==0 && !stack[index-1].function )
+		Error( err_unexpected_final_bracket );
+
+
+	bool was_sign = stack[index-1].sign;
+
+
+	if( stack[index-1].function )
+	{
+		// the result of a function will be on 'stack[index-1]'
+		// and then at the end we'll set the correct type (numerical value) of this element
+		CallFunction(stack[index-1].function_name, amount_of_parameters, index);
+	}
+	else
+	{
+		/*
+			there was a normal bracket (not a funcion)
+		*/
+		if( amount_of_parameters != 1 )
+			Error( err_unexpected_semicolon_operator );
+
+
+		/*
+			in the place where is the bracket we put the result
+		*/
+		stack[index-1] = stack[index];
+	}
+
+
+	/*
+		if there was a '-' character before the first bracket
+		we change the sign of the expression
+	*/
+	stack[index-1].sign = false;
+
+	if( was_sign )
+		stack[index-1].value.ChangeSign();
+
+	stack[index-1].type = Item::numerical_value;
+
+
+	/*
+		the pointer of the stack will be pointing on the next (non-existing now) element
+	*/
+	stack_index = index;
+}
+
+
+/*!
+	this method is putting the operator on the stack
+*/
+
+void PushOperatorIntoStack(Item & temp)
+{
+	if( stack_index < stack.size() )
+		stack[stack_index] = temp;
+	else
+		stack.push_back( temp );
+
+	++stack_index;
+}
+
+
+
+/*!
+	this method is reading a operator and if it's a final bracket
+	it's calling RollingUpFinalBracket() and reading a operator again
+*/
+int ReadOperatorAndCheckFinalBracket(Item & temp)
+{
+	do
+	{
+		if( ReadOperator(temp) == 1 )
+		{
+			/*
+				the string is finished
+			*/
+		return 1;
+		}
+
+		if( temp.type == Item::last_bracket )
+			RollingUpFinalBracket();
+
+	}
+	while( temp.type == Item::last_bracket );
+
+return 0;
+}
+
+
+/*!
+	we check wheter there are only numerical value's or 'semicolon' operators on the stack
+*/
+void CheckIntegrityOfStack()
+{
+	for(unsigned int i=0 ; i<stack_index; ++i)
+	{
+		if( stack[i].type != Item::numerical_value &&
+			stack[i].type != Item::semicolon)
+		{
+			/*
+				on the stack we must only have 'numerical_value' or 'semicolon' operator
+				if there is something another that means
+				we probably didn't close any of the 'first' bracket
+			*/
+			Error( err_stack_not_clear );
+		}
+	}
+}
+
+
+
+/*!
+	the main loop of parsing
+*/
+void Parse()
+{
+Item item;	
+int result_code;
+
+
+	while( true )
+	{
+		if( pstop_calculating && pstop_calculating->WasStopSignal() )
+			Error( err_interrupt );
+
+		result_code = ReadValueVariableOrFunctionAndPushItIntoStack( item );
+
+		if( result_code == 0 )
+		{
+			if( item.type == Item::first_bracket )
+				continue;
+			
+			result_code = ReadOperatorAndCheckFinalBracket( item );
+		}
+	
+		
+		if( result_code==1 || item.type==Item::semicolon )
+		{
+			/*
+				the string is finished or the 'semicolon' operator has appeared
+			*/
+
+			if( stack_index == 0 )
+				Error( err_nothing_has_read );
+			
+			TryRollingUpStack();
+
+			if( result_code == 1 )
+			{
+				CheckIntegrityOfStack();
+
+			return;
+			}
+		}			
+	
+
+		PushOperatorIntoStack( item );
+		TryRollingUpStackWithOperatorPriority();
+	}
+}
+
+/*!
+	this method is called at the end of the parsing process
+
+	on our stack we can have another value than 'numerical_values' for example
+	when someone use the operator ';' in the global scope or there was an error during
+	parsing and the parser hasn't finished its job
+
+	if there was an error the stack is cleaned up now
+	otherwise we resize stack and leave on it only 'numerical_value' items
+*/
+void NormalizeStack()
+{
+	if( error!=err_ok || stack_index==0 )
+	{
+		stack.clear();
+		return;
+	}
+	
+	
+	/*
+		'stack_index' tell us how many elements there are on the stack,
+		we must resize the stack now because 'stack_index' is using only for parsing
+		and stack has more (or equal) elements than value of 'stack_index'
+	*/
+	stack.resize( stack_index );
+
+	for(uint i=stack_index-1 ; i!=uint(-1) ; --i)
+	{
+		if( stack[i].type != Item::numerical_value )
+			stack.erase( stack.begin() + i );
+	}
+}
+
+
+public:
+
+
+/*!
+	the default constructor
+*/
+Parser(): default_stack_size(100)
+{
+	pstop_calculating = 0;
+	puser_variables   = 0;
+	puser_functions   = 0;
+	pfunction_local_variables = 0;
+	base              = 10;
+	deg_rad_grad      = 1;
+	error             = err_ok;
+	group             = 0;
+	comma             = '.';
+	comma2            = ',';
+	param_sep         = 0;
+
+	CreateFunctionsTable();
+	CreateVariablesTable();
+	CreateMathematicalOperatorsTable();
+}
+
+
+/*!
+	the assignment operator
+*/
+Parser<ValueType> & operator=(const Parser<ValueType> & p)
+{
+	pstop_calculating = p.pstop_calculating;
+	puser_variables   = p.puser_variables;
+	puser_functions   = p.puser_functions;
+	pfunction_local_variables = 0;
+	base              = p.base;
+	deg_rad_grad      = p.deg_rad_grad;
+	error             = p.error;
+	group             = p.group;
+	comma             = p.comma;
+	comma2            = p.comma2;
+	param_sep         = p.param_sep;
+
+	/*
+		we don't have to call 'CreateFunctionsTable()' etc.
+		we can only copy these tables
+	*/
+	functions_table   = p.functions_table;
+	variables_table   = p.variables_table;
+	operators_table   = p.operators_table;
+
+	visited_variables = p.visited_variables;
+	visited_functions = p.visited_functions;
+
+return *this;
+}
+
+
+/*!
+	the copying constructor
+*/
+Parser(const Parser<ValueType> & p): default_stack_size(p.default_stack_size)
+{
+	operator=(p);
+}
+
+
+/*!
+	the new base of mathematic system
+	default is 10
+*/
+void SetBase(int b)
+{
+	if( b>=2 && b<=16 )
+		base = b;
+}
+
+
+/*!
+	the unit of angles used in: sin,cos,tan,cot,asin,acos,atan,acot
+	0 - deg
+	1 - rad (default)
+	2 - grad
+*/
+void SetDegRadGrad(int angle)
+{
+	if( angle >= 0 || angle <= 2 )
+		deg_rad_grad = angle;
+}
+
+/*!
+	this method sets a pointer to the object which tell us whether we should stop
+	calculations
+*/
+void SetStopObject(const volatile StopCalculating * ps)
+{
+	pstop_calculating = ps;
+}
+
+
+/*!
+	this method sets the new table of user-defined variables
+	if you don't want any other variables just put zero value into the 'puser_variables' variable
+
+	(you can have only one table at the same time)
+*/
+void SetVariables(const Objects * pv)
+{
+	puser_variables = pv;
+}
+
+
+/*!
+	this method sets the new table of user-defined functions
+	if you don't want any other functions just put zero value into the 'puser_functions' variable
+
+	(you can have only one table at the same time)
+*/
+void SetFunctions(const Objects * pf)
+{
+	puser_functions = pf;
+}
+
+
+/*!
+	setting the group character
+	default zero (not used)
+*/
+void SetGroup(int g)
+{
+	group = g;
+}
+
+
+/*!
+	setting the main comma operator and the additional comma operator
+	the additional operator can be zero (which means it is not used)
+	default are: '.' and ','
+*/
+void SetComma(int c, int c2 = 0)
+{
+	comma  = c;
+	comma2 = c2;
+}
+
+
+/*!
+	setting an additional character which is used as a parameters separator
+	the main parameters separator is a semicolon (is used always)
+
+	this character is used also as a global separator
+*/
+void SetParamSep(int s)
+{
+	param_sep = s;
+}
+
+
+/*!
+	the main method using for parsing string
+*/
+ErrorCode Parse(const char * str)
+{
+	stack_index  = 0;
+	pstring      = str;
+	error        = err_ok;
+	calculated   = false;
+
+	stack.resize( default_stack_size );
+
+	try
+	{
+		Parse();
+	}
+	catch(ErrorCode c)
+	{
+		error = c;
+		calculated = false;
+	}
+
+	NormalizeStack();
+
+return error;
+}
+
+
+/*!
+	the main method using for parsing string
+*/
+ErrorCode Parse(const std::string & str)
+{
+	return Parse(str.c_str());
+}
+
+
+/*!
+	the main method using for parsing string
+*/
+ErrorCode Parse(const wchar_t * str)
+{
+	Misc::AssignString(wide_to_ansi, str);
+
+return Parse(wide_to_ansi.c_str());	
+}
+
+
+/*!
+	the main method using for parsing string
+*/
+ErrorCode Parse(const std::wstring & str)
+{
+	return Parse(str.c_str());
+}
+
+
+/*!
+	this method returns true is something was calculated
+	(at least one mathematical operator was used or a function or variable)
+	e.g. true if the string to Parse() looked like this:
+	"1+1"
+	"2*3"
+	"sin(5)"
+
+	if the string was e.g. "678" the result is false
+*/
+bool Calculated()
+{
+	return calculated;
+}
+
+
+};
+
+
+
+} // namespace
+
+
+#endif
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmaththreads.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,250 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmaththreads
+#define headerfilettmaththreads
+
+#include "ttmathtypes.h"
+
+#ifdef TTMATH_WIN32_THREADS
+#include <windows.h>
+#include <cstdio>
+#endif
+
+#ifdef TTMATH_POSIX_THREADS
+#include <pthread.h>
+#endif
+
+
+
+/*!
+	\file ttmaththreads.h
+    \brief Some objects used in multithreads environment
+*/
+
+
+/*
+	this is a simple skeleton of a program in multithreads environment:
+
+	#define TTMATH_MULTITHREADS
+	#include<ttmath/ttmath.h>
+	
+	TTMATH_MULTITHREADS_HELPER
+
+	int main()
+	{
+	[...]
+	}
+
+	make sure that macro TTMATH_MULTITHREADS is defined and (somewhere in *.cpp file)
+	use TTMATH_MULTITHREADS_HELPER macro (outside of any classes/functions/namespaces scope)
+*/
+
+
+namespace ttmath
+{
+
+
+#ifdef TTMATH_WIN32_THREADS
+
+	/*
+		we use win32 threads
+	*/
+
+
+	/*!
+		in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
+		somewhere in *.cpp file
+
+		(at the moment in win32 this macro does nothing)
+	*/
+	#define TTMATH_MULTITHREADS_HELPER
+
+
+	/*!
+		objects of this class are used to synchronize
+	*/
+	class ThreadLock
+	{
+		HANDLE mutex_handle;
+
+
+		void CreateName(char * buffer) const
+		{
+			#ifdef _MSC_VER
+			#pragma warning (disable : 4996)
+			// warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead.
+			#endif
+
+			sprintf(buffer, "TTMATH_LOCK_%ul", (unsigned long)GetCurrentProcessId());
+
+			#ifdef _MSC_VER
+			#pragma warning (default : 4996)
+			#endif
+		}
+
+
+	public:
+
+		bool Lock()
+		{
+		char buffer[50];
+
+			CreateName(buffer);
+			mutex_handle = CreateMutexA(0, false, buffer);
+
+			if( mutex_handle == 0 )
+				return false;
+
+			WaitForSingleObject(mutex_handle, INFINITE);
+
+		return true;
+		}
+
+
+		ThreadLock()
+		{
+			mutex_handle = 0;
+		}
+
+
+		~ThreadLock()
+		{
+			if( mutex_handle != 0 )
+			{
+				ReleaseMutex(mutex_handle);
+				CloseHandle(mutex_handle);
+			}
+		}
+	};
+
+#endif  // #ifdef TTMATH_WIN32_THREADS
+
+
+
+
+
+#ifdef TTMATH_POSIX_THREADS
+
+	/*
+		we use posix threads
+	*/
+
+
+	/*!
+		in multithreads environment you should use TTMATH_MULTITHREADS_HELPER macro
+		somewhere in *.cpp file
+		(this macro defines a pthread_mutex_t object used by TTMath library)
+	*/
+	#define TTMATH_MULTITHREADS_HELPER                          \
+	namespace ttmath                                            \
+	{                                                           \
+	pthread_mutex_t ttmath_mutex = PTHREAD_MUTEX_INITIALIZER;   \
+	}
+
+
+	/*!
+		ttmath_mutex will be defined by TTMATH_MULTITHREADS_HELPER macro 
+	*/
+	extern pthread_mutex_t ttmath_mutex;
+
+
+	/*!
+		objects of this class are used to synchronize
+	*/
+	class ThreadLock
+	{
+	public:
+
+		bool Lock()
+		{
+			if( pthread_mutex_lock(&ttmath_mutex) != 0 )
+				return false;
+
+		return true;
+		}
+
+
+		~ThreadLock()
+		{
+			pthread_mutex_unlock(&ttmath_mutex);
+		}
+	};
+
+#endif // #ifdef TTMATH_POSIX_THREADS
+
+
+
+
+#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
+
+	/*!
+		we don't use win32 and pthreads
+	*/
+
+	/*!
+	*/
+	#define TTMATH_MULTITHREADS_HELPER
+
+
+	/*!
+		objects of this class are used to synchronize
+		actually we don't synchronize, the method Lock() returns always 'false'
+	*/
+	class ThreadLock
+	{
+	public:
+
+		bool Lock()
+		{
+			return false;
+		}
+	};
+
+
+#endif // #if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
+
+
+
+
+
+} // namespace
+
+#endif
+
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathtypes.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,646 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2010, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef headerfilettmathtypes
+#define headerfilettmathtypes
+
+/*!
+	\file ttmathtypes.h
+    \brief constants used in the library
+    
+    As our library is written in header files (templates) we cannot use
+	constants like 'const int' etc. because we should have some source files
+	*.cpp to define this variables. Only what we can have are constants
+	defined by #define preprocessor macros.
+
+	All macros are preceded by TTMATH_ prefix
+*/
+
+
+#include <stdexcept>
+#include <sstream>
+#include <vector>
+
+/*!
+	the version of the library
+
+	TTMATH_PRERELEASE_VER is either zero or one
+	if zero that means this is the release version of the library
+*/
+#define TTMATH_MAJOR_VER		0
+#define TTMATH_MINOR_VER		9
+#define TTMATH_REVISION_VER		1
+#define TTMATH_PRERELEASE_VER	0
+
+
+/*!
+	TTMATH_DEBUG
+	this macro enables further testing during writing your code
+	you don't have to define it in a release mode
+
+	if this macro is set then macros TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT
+	are set as well	and these macros can throw an exception if a condition in it
+	is not fulfilled (look at the definition of TTMATH_ASSERT and TTMATH_REFERENCE_ASSERT)
+
+	TTMATH_RELEASE
+	if you are confident that your code is perfect you can define TTMATH_RELEASE
+	macro for example by using -D option in gcc
+	 gcc -DTTMATH_RELEASE -o myprogram myprogram.cpp 
+	or by defining this macro in your code before using any header files of this library
+
+	if TTMATH_RELEASE is not set then TTMATH_DEBUG is set automatically
+*/
+#ifndef TTMATH_RELEASE
+	#define TTMATH_DEBUG
+#endif
+
+
+
+namespace ttmath
+{
+
+#if !defined _M_X64 && !defined __x86_64__
+
+	/*!
+		we're using a 32bit platform
+	*/
+	#define TTMATH_PLATFORM32
+
+#else
+
+	/*!
+		we're using a 64bit platform
+	*/
+	#define TTMATH_PLATFORM64
+
+#endif
+
+
+
+/*!
+	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
+
+	/*!
+		on 32bit platforms one word (uint, sint) will be equal 32bits
+	*/
+	typedef unsigned int uint;
+	typedef signed   int sint;
+
+	/*!
+		this type is twice bigger than uint
+		(64bit on a 32bit platforms)
+
+		although C++ Standard - ANSI ISO IEC 14882:2003 doesn't define such a type (long long) 
+		but it is defined in C99 and in upcoming C++0x /3.9.1 (2)/ and many compilers support it
+
+		this type is used in UInt::MulTwoWords and UInt::DivTwoWords when macro TTMATH_NOASM is defined
+		but only on a 32bit platform
+	*/
+	#ifdef TTMATH_NOASM
+		typedef unsigned long long int ulint;
+	#endif
+
+	/*!
+		how many bits there are in the uint type
+	*/
+	#define TTMATH_BITS_PER_UINT 32u
+
+	/*!
+		the mask for the highest bit in the unsigned 32bit word (2^31)
+	*/
+	#define TTMATH_UINT_HIGHEST_BIT 2147483648u
+
+	/*!
+		the max value of the unsigned 32bit word (2^32 - 1)
+		(all bits equal one)
+	*/
+	#define TTMATH_UINT_MAX_VALUE 4294967295u
+
+	/*!
+		the number of words (32bit words on 32bit platform)
+		which are kept in built-in variables for a Big<> type
+		(these variables are defined in ttmathbig.h)
+	*/
+	#define TTMATH_BUILTIN_VARIABLES_SIZE 256u
+
+	/*!
+		this macro returns the number of machine words 
+		capable to hold min_bits bits
+		e.g. TTMATH_BITS(128) returns 4
+	*/
+	#define TTMATH_BITS(min_bits) ((min_bits-1)/32 + 1)
+
+#else
+
+	/*!
+		on 64bit platforms one word (uint, sint) will be equal 64bits
+	*/
+	#ifdef _MSC_VER
+		/* in VC 'long' type has 32 bits, __int64 is VC extension */
+		typedef unsigned __int64 uint;
+		typedef signed   __int64 sint;
+	#else
+		typedef unsigned long uint;
+		typedef signed   long sint;
+	#endif 
+
+	/*!
+		on 64bit platform we do not define ulint
+		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
+	*/
+	#define TTMATH_BITS_PER_UINT 64ul
+
+	/*!
+		the mask for the highest bit in the unsigned 64bit word (2^63)
+	*/
+	#define TTMATH_UINT_HIGHEST_BIT 9223372036854775808ul
+
+	/*!
+		the max value of the unsigned 64bit word (2^64 - 1)
+		(all bits equal one)
+	*/
+	#define TTMATH_UINT_MAX_VALUE 18446744073709551615ul
+
+	/*!
+		the number of words (64bit words on 64bit platforms)
+		which are kept in built-in variables for a Big<> type
+		(these variables are defined in ttmathbig.h)
+	*/
+	#define TTMATH_BUILTIN_VARIABLES_SIZE 128ul
+
+	/*!
+		this macro returns the number of machine words 
+		capable to hold min_bits bits
+		e.g. TTMATH_BITS(128) returns 2
+	*/
+	#define TTMATH_BITS(min_bits) ((min_bits-1)/64 + 1)
+
+#endif
+}
+
+
+#if defined(TTMATH_MULTITHREADS) && !defined(TTMATH_MULTITHREADS_NOSYNC)
+	#if !defined(TTMATH_POSIX_THREADS) && !defined(TTMATH_WIN32_THREADS)
+
+		#if defined(_WIN32)
+			#define TTMATH_WIN32_THREADS
+		#elif defined(unix) || defined(__unix__) || defined(__unix)
+			#define TTMATH_POSIX_THREADS
+		#endif
+
+	#endif
+#endif
+
+
+
+/*!
+	this variable defines how many iterations are performed
+	during some kind of calculating when we're making any long formulas
+	(for example Taylor series)
+
+	it's used in ExpSurrounding0(...), LnSurrounding1(...), Sin0pi05(...), etc.
+
+	note! there'll not be so many iterations, iterations are stopped when
+	there is no sense to continue calculating (for example when the result
+	still remains unchanged after adding next series and we know that the next
+	series are smaller than previous ones)
+*/
+#define TTMATH_ARITHMETIC_MAX_LOOP 10000
+
+
+
+/*!
+	this is a limit when calculating Karatsuba multiplication
+	if the size of a vector is smaller than TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE
+	the Karatsuba algorithm will use standard schoolbook multiplication
+*/
+#ifdef TTMATH_DEBUG_LOG
+	// if TTMATH_DEBUG_LOG is defined then we should use the same size regardless of the compiler
+	#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
+#else
+	#ifdef __GNUC__
+		#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 3
+	#else
+		#define TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE 5
+	#endif
+#endif
+
+
+/*!
+	this is a special value used when calculating the Gamma(x) function
+	if x is greater than this value then the Gamma(x) will be calculated using
+	some kind of series
+
+	don't use smaller values than about 100
+*/
+#define TTMATH_GAMMA_BOUNDARY 2000
+
+
+
+
+
+namespace ttmath
+{
+
+	/*!
+		lib type codes:
+		  asm_vc_32   - with asm code designed for Microsoft Visual C++ (32 bits)
+		  asm_gcc_32  - with asm code designed for GCC (32 bits)
+		  asm_vc_64   - with asm for VC (64 bit)
+		  asm_gcc_64  - with asm for GCC (64 bit)
+		  no_asm_32   - pure C++ version (32 bit) - without any asm code
+		  no_asm_64   - pure C++ version (64 bit) - without any asm code
+	*/
+	enum LibTypeCode
+	{
+	  asm_vc_32 = 0,
+	  asm_gcc_32,
+	  asm_vc_64,
+	  asm_gcc_64,
+	  no_asm_32,
+	  no_asm_64
+	};
+
+
+	/*!
+		error codes
+	*/
+	enum ErrorCode
+	{
+		err_ok = 0,
+		err_nothing_has_read,
+		err_unknown_character,
+		err_unexpected_final_bracket,
+		err_stack_not_clear,
+		err_unknown_variable,
+		err_division_by_zero,
+		err_interrupt,
+		err_overflow,
+		err_unknown_function,
+		err_unknown_operator,
+		err_unexpected_semicolon_operator,
+		err_improper_amount_of_arguments,
+		err_improper_argument,
+		err_unexpected_end,
+		err_internal_error,
+		err_incorrect_name,
+		err_incorrect_value,
+		err_variable_exists,
+		err_variable_loop,
+		err_functions_loop,
+		err_must_be_only_one_value,
+		err_object_exists,
+		err_unknown_object,
+		err_still_calculating,
+		err_in_short_form_used_function,
+		err_percent_from
+	};
+
+
+	/*!
+		this struct is used when converting to/from a string
+		/temporarily only in Big::ToString() and Big::FromString()/
+	*/
+	struct Conv
+	{
+		/*!
+			base (radix) on which the value will be shown (or read)
+			default: 10
+		*/
+		uint base;
+
+
+		/*!
+			used only in Big::ToString()
+			if true the value will be always shown in the scientific mode, e.g: 123e+30
+			default: false
+		*/
+		bool scient;
+
+
+		/*!
+			used only in Big::ToString()
+			if scient is false then the value will be print in the scientific mode
+			only if the exponent is greater than scien_from
+			default: 15
+		*/
+		sint scient_from;
+
+
+		/*!
+			if 'base_round' is true and 'base' is different from 2, 4, 8, or 16
+			and the result value is not an integer then we make an additional rounding
+			(after converting the last digit from the result is skipped)
+			default: true
+
+			e.g.
+			Conv c;
+			c.base_round = false;
+			Big<1, 1> a = "0.1";                       // decimal input
+			std::cout << a.ToString(c) << std::endl;   // the result is: 0.099999999
+		*/
+		bool base_round;
+
+
+		/*!
+			used only in Big::ToString()
+			tells how many digits after comma are possible
+			default: -1 which means all digits are printed
+
+			set it to zero if you want integer value only
+
+			for example when the value is:
+				12.345678 and 'round' is 4
+			then the result will be 
+				12.3457   (the last digit was rounded)
+		*/
+		sint round;
+
+
+		/*!
+			if true that not mattered digits in the mantissa will be cut off
+			(zero characters at the end -- after the comma operator)
+			e.g. 1234,78000 will be: 1234,78
+			default: true
+		*/
+		bool trim_zeroes;
+
+
+		/*!
+			the main comma operator (used when reading and writing)
+			default is a dot '.'
+		*/
+		uint comma;
+
+
+		/*!
+			additional comma operator (used only when reading) 
+			if you don't want it just set it to zero
+			default is a comma ','
+
+			this allowes you to convert from a value:
+			123.45 as well as from 123,45
+		*/
+		uint comma2;
+
+
+		/*!
+			it sets the character which is used for grouping
+			if group=' ' then: 1234,56789 will be printed as: 1 234,567 89
+
+			if you don't want grouping just set it to zero (which is default)
+		*/
+		uint group;
+
+
+		/*!
+		*/
+		uint group_exp; // not implemented yet
+
+
+
+
+		Conv()
+		{
+			// default values
+			base         = 10;
+			scient       = false;
+			scient_from  = 15;
+			base_round   = true;
+			round        = -1;
+			trim_zeroes  = true;
+			comma        = '.';
+			comma2       = ',';
+			group        = 0;
+			group_exp    = 0;
+		}
+	};
+
+
+
+	/*!
+		this simple class can be used in multithreading model
+		(you can write your own class derived from this one)
+
+		for example: in some functions like Factorial() 
+		/at the moment only Factorial/ you can give a pointer to 
+		the 'stop object', if the method WasStopSignal() of this 
+		object returns true that means we should break the calculating
+		and return
+	*/
+	class StopCalculating
+	{
+	public:
+		virtual bool WasStopSignal() const volatile { return false; }
+		virtual ~StopCalculating(){}
+	};
+
+
+	/*!
+		a small class which is useful when compiling with gcc
+
+		object of this type holds the name and the line of a file
+		in which the macro TTMATH_ASSERT or TTMATH_REFERENCE_ASSERT was used
+	*/
+	class ExceptionInfo
+	{
+	const char * file;
+	int line;
+
+	public:
+		ExceptionInfo() : file(0), line(0) {}
+		ExceptionInfo(const char * f, int l) : file(f), line(l) {}
+
+		std::string Where() const
+		{
+			if( !file )
+				return "unknown";
+
+			std::ostringstream result;
+			result << file << ":" << line;
+
+		return result.str();
+		}
+	};
+
+
+	/*!
+		A small class used for reporting 'reference' errors
+
+		In the library is used macro TTMATH_REFERENCE_ASSERT which
+		can throw an exception of this type
+
+		If you compile with gcc you can get a small benefit 
+		from using method Where() (it returns std::string) with
+		the name and the line of a file where the macro TTMATH_REFERENCE_ASSERT
+		was used)
+
+		What is the 'reference' error?
+		Some kind of methods use a reference as their argument to another object,
+		and the another object not always can be the same which is calling, e.g.
+			Big<1,2> foo(10);
+			foo.Mul(foo); // this is incorrect
+		above method Mul is making something more with 'this' object and 
+		'this' cannot be passed as the argument because the result will be undefined
+
+		macro TTMATH_REFERENCE_ASSERT helps us to solve the above problem
+
+		note! some methods can use 'this' object as the argument
+		for example this code is correct:
+			UInt<2> foo(10);
+			foo.Add(foo);
+		but there are only few methods which can do that
+	*/
+	class ReferenceError : public std::logic_error, public ExceptionInfo
+	{
+	public:
+
+		ReferenceError() : std::logic_error("reference error")
+		{
+		}
+
+		ReferenceError(const char * f, int l) :
+							std::logic_error("reference error"), ExceptionInfo(f,l)
+		{
+		}
+
+		std::string Where() const
+		{
+			return ExceptionInfo::Where();
+		}
+	};
+
+
+	/*!
+		a small class used for reporting errors
+
+		in the library is used macro TTMATH_ASSERT which
+		(if the condition in it is false) throw an exception
+		of this type
+
+		if you compile with gcc you can get a small benefit 
+		from using method Where() (it returns std::string) with
+		the name and the line of a file where the macro TTMATH_ASSERT
+		was used)
+	*/
+	class RuntimeError : public std::runtime_error, public ExceptionInfo
+	{
+	public:
+
+		RuntimeError() : std::runtime_error("internal error")
+		{
+		}
+
+		RuntimeError(const char * f, int l) :
+						std::runtime_error("internal error"), ExceptionInfo(f,l)
+		{
+		}
+
+		std::string Where() const
+		{
+			return ExceptionInfo::Where();
+		}
+	};
+
+
+
+	/*!
+		look at the description of macros TTMATH_RELEASE and TTMATH_DEBUG
+	*/
+	#ifdef TTMATH_DEBUG
+
+		#if defined(__FILE__) && defined(__LINE__)
+
+			#define TTMATH_REFERENCE_ASSERT(expression) \
+				if( &(expression) == this ) throw ttmath::ReferenceError(__FILE__, __LINE__);
+
+			#define TTMATH_ASSERT(expression) \
+				if( !(expression) ) throw ttmath::RuntimeError(__FILE__, __LINE__);
+
+		#else
+
+			#define TTMATH_REFERENCE_ASSERT(expression) \
+				if( &(expression) == this ) throw ReferenceError();
+
+			#define TTMATH_ASSERT(expression) \
+				if( !(expression) ) throw RuntimeError();
+		#endif
+
+	#else
+		#define TTMATH_REFERENCE_ASSERT(expression)
+		#define TTMATH_ASSERT(expression)
+	#endif
+
+
+
+	#ifdef TTMATH_DEBUG_LOG
+		#define TTMATH_LOG(msg)                             PrintLog(msg, std::cout);
+		#define TTMATH_LOGC(msg, carry)                     PrintLog(msg, carry, std::cout);
+		#define TTMATH_VECTOR_LOG(msg, vector, len)         PrintVectorLog(msg, std::cout, vector, len);
+		#define TTMATH_VECTOR_LOGC(msg, carry, vector, len) PrintVectorLog(msg, carry, std::cout, vector, len);
+	#else
+		#define TTMATH_LOG(msg)
+		#define TTMATH_LOGC(msg, carry)
+		#define TTMATH_VECTOR_LOG(msg, vector, len)
+		#define TTMATH_VECTOR_LOGC(msg, carry, vector, len)
+	#endif
+
+
+
+
+} // namespace
+
+
+#endif
+
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,3506 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/*
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathuint
+#define headerfilettmathuint
+
+
+/*!
+    \file ttmathuint.h
+    \brief template class UInt<uint>
+*/
+
+#include <iostream>
+#include <iomanip>
+
+
+#include "ttmathtypes.h"
+#include "ttmathmisc.h"
+
+
+
+/*!
+    \brief a namespace for the TTMath library
+*/
+namespace ttmath
+{
+
+/*!
+    \brief UInt implements a big integer value without a sign
+
+    value_size - how many bytes specify our value
+        on 32bit platforms: value_size=1 -> 4 bytes -> 32 bits
+        on 64bit platforms: value_size=1 -> 8 bytes -> 64 bits
+    value_size = 1,2,3,4,5,6....
+*/
+template<uint value_size>
+class UInt
+{
+public:
+
+    /*!
+        buffer for the integer value
+          table[0] - the lowest word of the value
+    */
+    uint table[value_size];
+
+
+
+    /*!
+        some methods used for debugging purposes
+    */
+
+
+    /*!
+        this method is only for debugging purposes or when we want to make
+        a table of a variable (constant) in ttmathbig.h
+
+        it prints the table in a nice form of several columns
+    */
+    template<class ostream_type>
+    void PrintTable(ostream_type & output) const
+    {
+        // how many columns there'll be
+        const int columns = 8;
+
+        int c = 1;
+        for(int i=value_size-1 ; i>=0 ; --i)
+        {
+            output << "0x" << std::setfill('0');
+
+            #ifdef TTMATH_PLATFORM32
+                output << std::setw(8);
+            #else
+                output << std::setw(16);
+            #endif
+
+            output << std::hex << table[i];
+
+            if( i>0 )
+            {
+                output << ", ";
+
+                if( ++c > columns )
+                {
+                    output << std::endl;
+                    c = 1;
+                }
+            }
+        }
+
+        output << std::dec << std::endl;
+    }
+
+
+    /*!
+        this method is used when macro TTMATH_DEBUG_LOG is defined
+    */
+    template<class char_type, class ostream_type>
+    static void PrintVectorLog(const char_type * msg, ostream_type & output, const uint * vector, uint vector_len)
+    {
+        output << msg << std::endl;
+
+        for(uint i=0 ; i<vector_len ; ++i)
+            output << " table[" << i << "]: " << vector[i] << std::endl;
+    }
+
+
+    /*!
+        this method is used when macro TTMATH_DEBUG_LOG is defined
+    */
+    template<class char_type, class ostream_type>
+    static void PrintVectorLog(const char_type * msg, uint carry, ostream_type & output, const uint * vector, uint vector_len)
+    {
+        PrintVectorLog(msg, output, vector, vector_len);
+        output << " carry: " << carry << std::endl;
+    }
+
+
+    /*!
+        this method is used when macro TTMATH_DEBUG_LOG is defined
+    */
+    template<class char_type, class ostream_type>
+    void PrintLog(const char_type * msg, ostream_type & output) const
+    {
+        PrintVectorLog(msg, output, table, value_size);
+    }
+
+
+    /*!
+        this method is used when macro TTMATH_DEBUG_LOG is defined
+    */
+    template<class char_type, class ostream_type>
+    void PrintLog(const char_type * msg, uint carry, ostream_type & output) const
+    {
+        PrintVectorLog(msg, output, table, value_size);
+        output << " carry: " << carry << std::endl;
+    }
+
+
+    /*!
+        this method returns the size of the table
+    */
+    uint Size() const
+    {
+        return value_size;
+    }
+
+
+    /*!
+        this method sets zero
+    */
+    void SetZero()
+    {
+        // in the future here can be 'memset'
+
+        for(uint i=0 ; i<value_size ; ++i)
+            table[i] = 0;
+
+        TTMATH_LOG("UInt::SetZero")
+    }
+
+
+    /*!
+        this method sets one
+    */
+    void SetOne()
+    {
+        SetZero();
+        table[0] = 1;
+
+        TTMATH_LOG("UInt::SetOne")
+    }
+
+
+    /*!
+        this method sets the max value which this class can hold
+        (all bits will be one)
+    */
+    void SetMax()
+    {
+        for(uint i=0 ; i<value_size ; ++i)
+            table[i] = TTMATH_UINT_MAX_VALUE;
+
+        TTMATH_LOG("UInt::SetMax")
+    }
+
+
+    /*!
+        this method sets the min value which this class can hold
+        (for an unsigned integer value the zero is the smallest value)
+    */
+    void SetMin()
+    {
+        SetZero();
+
+        TTMATH_LOG("UInt::SetMin")
+    }
+
+
+
+#ifdef TTMATH_PLATFORM32
+
+    /*!
+        this method copies the value stored in an another table
+        (warning: first values in temp_table are the highest words -- it's different
+        from our table)
+
+        we copy as many words as it is possible
+
+        if temp_table_len is bigger than value_size we'll try to round
+        the lowest word from table depending on the last not used bit in temp_table
+        (this rounding isn't a perfect rounding -- look at the description below)
+
+        and if temp_table_len is smaller than value_size we'll clear the rest words
+        in the table
+    */
+    void SetFromTable(const uint * temp_table, uint temp_table_len)
+    {
+        uint temp_table_index = 0;
+        sint i; // 'i' with a sign
+
+        for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
+            table[i] = temp_table[ temp_table_index ];
+
+
+        // rounding mantissa
+        if( temp_table_index < temp_table_len )
+        {
+            if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+            {
+                /*
+                    very simply rounding
+                    if the bit from not used last word from temp_table is set to one
+                    we're rouding the lowest word in the table
+
+                    in fact there should be a normal addition but
+                    we don't use Add() or AddTwoInts() because these methods
+                    can set a carry and then there'll be a small problem
+                    for optimization
+                */
+                if( table[0] != TTMATH_UINT_MAX_VALUE )
+                    ++table[0];
+            }
+        }
+
+        // cleaning the rest of the mantissa
+        for( ; i>=0 ; --i)
+            table[i] = 0;
+
+
+        TTMATH_LOG("UInt::SetFromTable")
+    }
+
+#endif
+
+
+#ifdef TTMATH_PLATFORM64
+    /*!
+        this method copies the value stored in an another table
+        (warning: first values in temp_table are the highest words -- it's different
+        from our table)
+
+        ***this method is created only on a 64bit platform***
+
+        we copy as many words as it is possible
+
+        if temp_table_len is bigger than value_size we'll try to round
+        the lowest word from table depending on the last not used bit in temp_table
+        (this rounding isn't a perfect rounding -- look at the description below)
+
+        and if temp_table_len is smaller than value_size we'll clear the rest words
+        in the table
+
+        warning: we're using 'temp_table' as a pointer at 32bit words
+    */
+    void SetFromTable(const unsigned int * temp_table, uint temp_table_len)
+    {
+        uint temp_table_index = 0;
+        sint i; // 'i' with a sign
+
+        for(i=value_size-1 ; i>=0 && temp_table_index<temp_table_len; --i, ++temp_table_index)
+        {
+            table[i] = uint(temp_table[ temp_table_index ]) << 32;
+
+            ++temp_table_index;
+
+            if( temp_table_index<temp_table_len )
+                table[i] |= temp_table[ temp_table_index ];
+        }
+
+
+        // rounding mantissa
+        if( temp_table_index < temp_table_len )
+        {
+            if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
+            {
+                /*
+                    very simply rounding
+                    if the bit from not used last word from temp_table is set to one
+                    we're rouding the lowest word in the table
+
+                    in fact there should be a normal addition but
+                    we don't use Add() or AddTwoInts() because these methods
+                    can set a carry and then there'll be a small problem
+                    for optimization
+                */
+                if( table[0] != TTMATH_UINT_MAX_VALUE )
+                    ++table[0];
+            }
+        }
+
+        // cleaning the rest of the mantissa
+        for( ; i >= 0 ; --i)
+            table[i] = 0;
+
+        TTMATH_LOG("UInt::SetFromTable")
+    }
+
+#endif
+
+
+
+
+
+    /*!
+    *
+    *   basic mathematic functions
+    *
+    */
+
+
+
+
+    /*!
+        this method adds one to the existing value
+    */
+    uint AddOne()
+    {
+        return AddInt(1);
+    }
+
+
+    /*!
+        this method subtracts one from the existing value
+    */
+    uint SubOne()
+    {
+        return SubInt(1);
+    }
+
+
+private:
+
+
+    /*!
+        an auxiliary method for moving bits into the left hand side
+
+        this method moves only words
+    */
+    void RclMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c)
+    {
+        rest_bits      = bits % TTMATH_BITS_PER_UINT;
+        uint all_words = bits / TTMATH_BITS_PER_UINT;
+        uint mask      = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
+
+
+        if( all_words >= value_size )
+        {
+            if( all_words == value_size && rest_bits == 0 )
+                last_c = table[0] & 1;
+            // else: last_c is default set to 0
+
+            // clearing
+            for(uint i = 0 ; i<value_size ; ++i)
+                table[i] = mask;
+
+            rest_bits = 0;
+        }
+        else
+        if( all_words > 0 )
+        {
+            // 0 < all_words < value_size
+
+            sint first, second;
+            last_c = table[value_size - all_words] & 1; // all_words is greater than 0
+
+            // copying the first part of the value
+            for(first = value_size-1, second=first-all_words ; second>=0 ; --first, --second)
+                table[first] = table[second];
+
+            // setting the rest to 'c'
+            for( ; first>=0 ; --first )
+                table[first] = mask;
+        }
+
+        TTMATH_LOG("UInt::RclMoveAllWords")
+    }
+
+public:
+
+    /*!
+        moving all bits into the left side 'bits' times
+        return value <- this <- C
+
+        bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
+        or it can be even bigger then all bits will be set to 'c'
+
+        the value c will be set into the lowest bits
+        and the method returns state of the last moved bit
+    */
+    uint Rcl(uint bits, uint c=0)
+    {
+    uint last_c    = 0;
+    uint rest_bits = bits;
+
+        if( bits == 0 )
+            return 0;
+
+        if( bits >= TTMATH_BITS_PER_UINT )
+            RclMoveAllWords(rest_bits, last_c, bits, c);
+
+        if( rest_bits == 0 )
+        {
+            TTMATH_LOG("UInt::Rcl")
+            return last_c;
+        }
+
+        // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
+        if( rest_bits == 1 )
+        {
+            last_c = Rcl2_one(c);
+        }
+        else if( rest_bits == 2 )
+        {
+            // performance tests showed that for rest_bits==2 it's better to use Rcl2_one twice instead of Rcl2(2,c)
+            Rcl2_one(c);
+            last_c = Rcl2_one(c);
+        }
+        else
+        {
+            last_c = Rcl2(rest_bits, c);
+        }
+
+        TTMATH_LOGC("UInt::Rcl", last_c)
+
+    return last_c;
+    }
+
+private:
+
+    /*!
+        an auxiliary method for moving bits into the right hand side
+
+        this method moves only words
+    */
+    void RcrMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c)
+    {
+        rest_bits      = bits % TTMATH_BITS_PER_UINT;
+        uint all_words = bits / TTMATH_BITS_PER_UINT;
+        uint mask      = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
+
+
+        if( all_words >= value_size )
+        {
+            if( all_words == value_size && rest_bits == 0 )
+                last_c = (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
+            // else: last_c is default set to 0
+
+            // clearing
+            for(uint i = 0 ; i<value_size ; ++i)
+                table[i] = mask;
+
+            rest_bits = 0;
+        }
+        else if( all_words > 0 )
+        {
+            // 0 < all_words < value_size
+
+            uint first, second;
+            last_c = (table[all_words - 1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0; // all_words is > 0
+
+            // copying the first part of the value
+            for(first=0, second=all_words ; second<value_size ; ++first, ++second)
+                table[first] = table[second];
+
+            // setting the rest to 'c'
+            for( ; first<value_size ; ++first )
+                table[first] = mask;
+        }
+
+        TTMATH_LOG("UInt::RcrMoveAllWords")
+    }
+
+public:
+
+    /*!
+        moving all bits into the right side 'bits' times
+        c -> this -> return value
+
+        bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
+        or it can be even bigger then all bits will be set to 'c'
+
+        the value c will be set into the highest bits
+        and the method returns state of the last moved bit
+    */
+    uint Rcr(uint bits, uint c=0)
+    {
+    uint last_c    = 0;
+    uint rest_bits = bits;
+
+        if( bits == 0 )
+            return 0;
+
+        if( bits >= TTMATH_BITS_PER_UINT )
+            RcrMoveAllWords(rest_bits, last_c, bits, c);
+
+        if( rest_bits == 0 )
+        {
+            TTMATH_LOG("UInt::Rcr")
+            return last_c;
+        }
+
+        // rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
+        if( rest_bits == 1 )
+        {
+            last_c = Rcr2_one(c);
+        }
+        else if( rest_bits == 2 )
+        {
+            // performance tests showed that for rest_bits==2 it's better to use Rcr2_one twice instead of Rcr2(2,c)
+            Rcr2_one(c);
+            last_c = Rcr2_one(c);
+        }
+        else
+        {
+            last_c = Rcr2(rest_bits, c);
+        }
+
+        TTMATH_LOGC("UInt::Rcr", last_c)
+
+    return last_c;
+    }
+
+
+    /*!
+        this method moves all bits into the left side
+        (it returns value how many bits have been moved)
+    */
+    uint CompensationToLeft()
+    {
+        uint moving = 0;
+
+        // a - index a last word which is different from zero
+        sint a;
+        for(a=value_size-1 ; a>=0 && table[a]==0 ; --a);
+
+        if( a < 0 )
+            return moving; // all words in table have zero
+
+        if( a != value_size-1 )
+        {
+            moving += ( value_size-1 - a ) * TTMATH_BITS_PER_UINT;
+
+            // moving all words
+            sint i;
+            for(i=value_size-1 ; a>=0 ; --i, --a)
+                table[i] = table[a];
+
+            // setting the rest word to zero
+            for(; i>=0 ; --i)
+                table[i] = 0;
+        }
+
+        uint moving2 = FindLeadingBitInWord( table[value_size-1] );
+        // moving2 is different from -1 because the value table[value_size-1]
+        // is not zero
+
+        moving2 = TTMATH_BITS_PER_UINT - moving2 - 1;
+        Rcl(moving2);
+
+        TTMATH_LOG("UInt::CompensationToLeft")
+
+    return moving + moving2;
+    }
+
+
+    /*!
+        this method looks for the highest set bit
+
+        result:
+            if 'this' is not zero:
+                return value - true
+                'table_id'   - the index of a word <0..value_size-1>
+                'index'      - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
+
+            if 'this' is zero:
+                return value - false
+                both 'table_id' and 'index' are zero
+    */
+    bool FindLeadingBit(uint & table_id, uint & index) const
+    {
+        for(table_id=value_size-1 ; table_id!=0 && table[table_id]==0 ; --table_id);
+
+        if( table_id==0 && table[table_id]==0 )
+        {
+            // is zero
+            index = 0;
+
+        return false;
+        }
+
+        // table[table_id] is different from 0
+        index = FindLeadingBitInWord( table[table_id] );
+
+    return true;
+    }
+
+
+    /*!
+        this method looks for the smallest set bit
+
+        result:
+            if 'this' is not zero:
+                return value - true
+                'table_id'   - the index of a word <0..value_size-1>
+                'index'      - the index of this set bit in the word <0..TTMATH_BITS_PER_UINT)
+
+            if 'this' is zero:
+                return value - false
+                both 'table_id' and 'index' are zero
+    */
+    bool FindLowestBit(uint & table_id, uint & index) const
+    {
+        for(table_id=0 ; table_id<value_size && table[table_id]==0 ; ++table_id);
+
+        if( table_id >= value_size )
+        {
+            // is zero
+            index    = 0;
+            table_id = 0;
+
+        return false;
+        }
+
+        // table[table_id] is different from 0
+        index = FindLowestBitInWord( table[table_id] );
+
+    return true;
+    }
+
+
+    /*!
+        getting the 'bit_index' bit
+
+        bit_index bigger or equal zero
+    */
+    uint GetBit(uint bit_index) const
+    {
+        TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
+
+        uint index = bit_index / TTMATH_BITS_PER_UINT;
+        uint bit   = bit_index % TTMATH_BITS_PER_UINT;
+
+        uint temp = table[index];
+        uint res  = SetBitInWord(temp, bit);
+
+    return res;
+    }
+
+
+    /*!
+        setting the 'bit_index' bit
+        and returning the last state of the bit
+
+        bit_index bigger or equal zero
+    */
+    uint SetBit(uint bit_index)
+    {
+        TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
+
+        uint index = bit_index / TTMATH_BITS_PER_UINT;
+        uint bit   = bit_index % TTMATH_BITS_PER_UINT;
+        uint res   = SetBitInWord(table[index], bit);
+
+        TTMATH_LOG("UInt::SetBit")
+
+    return res;
+    }
+
+
+    /*!
+        this method performs a bitwise operation AND
+    */
+    void BitAnd(const UInt<value_size> & ss2)
+    {
+        for(uint x=0 ; x<value_size ; ++x)
+            table[x] &= ss2.table[x];
+
+        TTMATH_LOG("UInt::BitAnd")
+    }
+
+
+    /*!
+        this method performs a bitwise operation OR
+    */
+    void BitOr(const UInt<value_size> & ss2)
+    {
+        for(uint x=0 ; x<value_size ; ++x)
+            table[x] |= ss2.table[x];
+
+        TTMATH_LOG("UInt::BitOr")
+    }
+
+
+    /*!
+        this method performs a bitwise operation XOR
+    */
+    void BitXor(const UInt<value_size> & ss2)
+    {
+        for(uint x=0 ; x<value_size ; ++x)
+            table[x] ^= ss2.table[x];
+
+        TTMATH_LOG("UInt::BitXor")
+    }
+
+
+    /*!
+        this method performs a bitwise operation NOT
+    */
+    void BitNot()
+    {
+        for(uint x=0 ; x<value_size ; ++x)
+            table[x] = ~table[x];
+
+        TTMATH_LOG("UInt::BitNot")
+    }
+
+
+    /*!
+        this method performs a bitwise operation NOT but only
+        on the range of <0, leading_bit>
+
+        for example:
+            BitNot2(8) = BitNot2( 1000(bin) ) = 111(bin) = 7
+    */
+    void BitNot2()
+    {
+    uint table_id, index;
+
+        if( FindLeadingBit(table_id, index) )
+        {
+            for(uint x=0 ; x<table_id ; ++x)
+                table[x] = ~table[x];
+
+            uint mask  = TTMATH_UINT_MAX_VALUE;
+            uint shift = TTMATH_BITS_PER_UINT - index - 1;
+
+            if(shift)
+                mask >>= shift;
+
+            table[table_id] ^= mask;
+        }
+        else
+            table[0] = 1;
+
+
+        TTMATH_LOG("UInt::BitNot2")
+    }
+
+
+
+    /*!
+     *
+     * Multiplication
+     *
+     *
+    */
+
+public:
+
+    /*!
+        multiplication: this = this * ss2
+
+        it can return a carry
+    */
+    uint MulInt(uint ss2)
+    {
+    uint r1, r2, x1;
+    uint c = 0;
+
+        UInt<value_size> u(*this);
+        SetZero();
+
+        if( ss2 == 0 )
+        {
+            TTMATH_LOGC("UInt::MulInt(uint)", 0)
+            return 0;
+        }
+
+        for(x1=0 ; x1<value_size-1 ; ++x1)
+        {
+            MulTwoWords(u.table[x1], ss2, &r2, &r1);
+            c += AddTwoInts(r2,r1,x1);
+        }
+
+        // x1 = value_size-1  (last word)
+        MulTwoWords(u.table[x1], ss2, &r2, &r1);
+        c += (r2!=0) ? 1 : 0;
+        c += AddInt(r1, x1);
+
+        TTMATH_LOGC("UInt::MulInt(uint)", c)
+
+    return (c==0)? 0 : 1;
+    }
+
+
+    /*!
+        multiplication: result = this * ss2
+
+        we're using this method only when result_size is greater than value_size
+        if so there will not be a carry
+    */
+    template<uint result_size>
+    void MulInt(uint ss2, UInt<result_size> & result) const
+    {
+    TTMATH_ASSERT( result_size > value_size )
+
+    uint r2,r1;
+    uint x1size=value_size;
+    uint x1start=0;
+
+        result.SetZero();
+
+        if( ss2 == 0 )
+        {
+            TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
+            return;
+        }
+
+        if( value_size > 2 )
+        {
+            // if the value_size is smaller than or equal to 2
+            // there is no sense to set x1size and x1start to another values
+
+            for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
+
+            if( x1size == 0 )
+            {
+                TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
+                return;
+            }
+
+            for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
+        }
+
+        for(uint x1=x1start ; x1<x1size ; ++x1)
+        {
+            MulTwoWords(table[x1], ss2, &r2, &r1 );
+            result.AddTwoInts(r2,r1,x1);
+        }
+
+        TTMATH_VECTOR_LOG("UInt::MulInt(uint, UInt<>)", result.table, result_size)
+
+    return;
+    }
+
+
+
+    /*!
+        the multiplication 'this' = 'this' * ss2
+
+        algorithm: 100 - means automatically choose the fastest algorithm
+    */
+    uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
+    {
+        switch( algorithm )
+        {
+        case 1:
+            return Mul1(ss2);
+
+        case 2:
+            return Mul2(ss2);
+
+        case 3:
+            return Mul3(ss2);
+
+        case 100:
+        default:
+            return MulFastest(ss2);
+        }
+    }
+
+
+    /*!
+        the multiplication 'result' = 'this' * ss2
+
+        since the 'result' is twice bigger than 'this' and 'ss2'
+        this method never returns a carry
+
+        algorithm: 100 - means automatically choose the fastest algorithm
+    */
+    void MulBig(const UInt<value_size> & ss2,
+                UInt<value_size*2> & result,
+                uint algorithm = 100)
+    {
+        switch( algorithm )
+        {
+        case 1:
+            return Mul1Big(ss2, result);
+
+        case 2:
+            return Mul2Big(ss2, result);
+
+        case 3:
+            return Mul3Big(ss2, result);
+
+        case 100:
+        default:
+            return MulFastestBig(ss2, result);
+        }
+    }
+
+
+
+    /*!
+        the first version of the multiplication algorithm
+    */
+
+    /*!
+        multiplication: this = this * ss2
+
+        it returns carry if it has been
+    */
+    uint Mul1(const UInt<value_size> & ss2)
+    {
+    TTMATH_REFERENCE_ASSERT( ss2 )
+
+    UInt<value_size> ss1( *this );
+    SetZero();
+
+        for(uint i=0; i < value_size*TTMATH_BITS_PER_UINT ; ++i)
+        {
+            if( Add(*this) )
+            {
+                TTMATH_LOGC("UInt::Mul1", 1)
+                return 1;
+            }
+
+            if( ss1.Rcl(1) )
+                if( Add(ss2) )
+                {
+                    TTMATH_LOGC("UInt::Mul1", 1)
+                    return 1;
+                }
+        }
+
+        TTMATH_LOGC("UInt::Mul1", 0)
+
+    return 0;
+    }
+
+
+    /*!
+        multiplication: result = this * ss2
+
+        result is twice bigger than 'this' and 'ss2'
+        this method never returns carry
+    */
+    void Mul1Big(const UInt<value_size> & ss2_, UInt<value_size*2> & result)
+    {
+    UInt<value_size*2> ss2;
+    uint i;
+
+        // copying *this into result and ss2_ into ss2
+        for(i=0 ; i<value_size ; ++i)
+        {
+            result.table[i] = table[i];
+            ss2.table[i]    = ss2_.table[i];
+        }
+
+        // cleaning the highest bytes in result and ss2
+        for( ; i < value_size*2 ; ++i)
+        {
+            result.table[i] = 0;
+            ss2.table[i]    = 0;
+        }
+
+        // multiply
+        // (there will not be a carry)
+        result.Mul1( ss2 );
+
+        TTMATH_LOG("UInt::Mul1Big")
+    }
+
+
+
+    /*!
+        the second version of the multiplication algorithm
+
+        this algorithm is similar to the 'schoolbook method' which is done by hand
+    */
+
+    /*!
+        multiplication: this = this * ss2
+
+        it returns carry if it has been
+    */
+    uint Mul2(const UInt<value_size> & ss2)
+    {
+    UInt<value_size*2> result;
+    uint i, c = 0;
+
+        Mul2Big(ss2, result);
+
+        // copying result
+        for(i=0 ; i<value_size ; ++i)
+            table[i] = result.table[i];
+
+        // testing carry
+        for( ; i<value_size*2 ; ++i)
+            if( result.table[i] != 0 )
+            {
+                c = 1;
+                break;
+            }
+
+        TTMATH_LOGC("UInt::Mul2", c)
+
+    return c;
+    }
+
+
+    /*!
+        multiplication: result = this * ss2
+
+        result is twice bigger than this and ss2
+        this method never returns carry
+    */
+    void Mul2Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
+    {
+        Mul2Big2<value_size>(table, ss2.table, result);
+
+        TTMATH_LOG("UInt::Mul2Big")
+    }
+
+
+private:
+
+    /*!
+        an auxiliary method for calculating the multiplication
+
+        arguments we're taking as pointers (this is to improve the Mul3Big2()- avoiding
+        unnecessary copying objects), the result should be taken as a pointer too,
+        but at the moment there is no method AddTwoInts() which can operate on pointers
+    */
+    template<uint ss_size>
+    void Mul2Big2(const uint * ss1, const uint * ss2, UInt<ss_size*2> & result)
+    {
+    uint x1size  = ss_size, x2size  = ss_size;
+    uint x1start = 0,       x2start = 0;
+
+        if( ss_size > 2 )
+        {
+            // if the ss_size is smaller than or equal to 2
+            // there is no sense to set x1size (and others) to another values
+
+            for(x1size=ss_size ; x1size>0 && ss1[x1size-1]==0 ; --x1size);
+            for(x2size=ss_size ; x2size>0 && ss2[x2size-1]==0 ; --x2size);
+
+            for(x1start=0 ; x1start<x1size && ss1[x1start]==0 ; ++x1start);
+            for(x2start=0 ; x2start<x2size && ss2[x2start]==0 ; ++x2start);
+        }
+
+        Mul2Big3<ss_size>(ss1, ss2, result, x1start, x1size, x2start, x2size);
+    }
+
+
+
+    /*!
+        an auxiliary method for calculating the multiplication
+    */
+    template<uint ss_size>
+    void Mul2Big3(const uint * ss1, const uint * ss2, UInt<ss_size*2> & result, uint x1start, uint x1size, uint x2start, uint x2size)
+    {
+    uint r2, r1;
+
+        result.SetZero();
+
+        if( x1size==0 || x2size==0 )
+            return;
+
+        for(uint x1=x1start ; x1<x1size ; ++x1)
+        {
+            for(uint x2=x2start ; x2<x2size ; ++x2)
+            {
+                MulTwoWords(ss1[x1], ss2[x2], &r2, &r1);
+                result.AddTwoInts(r2, r1, x2+x1);
+                // here will never be a carry
+            }
+        }
+    }
+
+
+public:
+
+
+    /*!
+        multiplication: this = this * ss2
+
+        This is Karatsuba Multiplication algorithm, we're using it when value_size is greater than
+        or equal to TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE macro (defined in ttmathuint.h).
+        If value_size is smaller then we're using Mul2Big() instead.
+
+        Karatsuba multiplication:
+        Assume we have:
+            this = x = x1*B^m + x0
+            ss2  = y = y1*B^m + y0
+        where x0 and y0 are less than B^m
+        the product from multiplication we can show as:
+        x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
+        where
+            z2 = x1*y1
+            z1 = x1*y0 + x0*y1
+            z0 = x0*y0
+        this is standard schoolbook algorithm with O(n^2), Karatsuba observed that z1 can be given in other form:
+            z1 = (x1 + x0)*(y1 + y0) - z2 - z0    / z1 = (x1*y1 + x1*y0 + x0*y1 + x0*y0) - x1*y1 - x0*y0 = x1*y0 + x0*y1 /
+        and to calculate the multiplication we need only three multiplications (with some additions and subtractions)
+
+        Our objects 'this' and 'ss2' we divide into two parts and by using recurrence we calculate the multiplication.
+        Karatsuba multiplication has O( n^(ln(3)/ln(2)) )
+    */
+    uint Mul3(const UInt<value_size> & ss2)
+    {
+    UInt<value_size*2> result;
+    uint i, c = 0;
+
+        Mul3Big(ss2, result);
+
+        // copying result
+        for(i=0 ; i<value_size ; ++i)
+            table[i] = result.table[i];
+
+        // testing carry
+        for( ; i<value_size*2 ; ++i)
+            if( result.table[i] != 0 )
+            {
+                c = 1;
+                break;
+            }
+
+        TTMATH_LOGC("UInt::Mul3", c)
+
+    return c;
+    }
+
+
+
+    /*!
+        multiplication: result = this * ss2
+
+        result is twice bigger than this and ss2,
+        this method never returns carry,
+        (Karatsuba multiplication)
+    */
+    void Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
+    {
+        Mul3Big2<value_size>(table, ss2.table, result.table);
+
+        TTMATH_LOG("UInt::Mul3Big")
+    }
+
+
+
+private:
+
+    /*!
+        an auxiliary method for calculating the Karatsuba multiplication
+
+        result_size is equal ss_size*2
+    */
+    template<uint ss_size>
+    void Mul3Big2(const uint * ss1, const uint * ss2, uint * result)
+    {
+    const uint * x1, * x0, * y1, * y0;
+
+
+        if( ss_size>1 && ss_size<TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
+        {
+            UInt<ss_size*2> res;
+            Mul2Big2<ss_size>(ss1, ss2, res);
+
+            for(uint i=0 ; i<ss_size*2 ; ++i)
+                result[i] = res.table[i];
+
+        return;
+        }
+        else
+        if( ss_size == 1 )
+        {
+            return MulTwoWords(*ss1, *ss2, &result[1], &result[0]);
+        }
+
+
+        if( (ss_size & 1) == 1 )
+        {
+            // ss_size is odd
+            x0 = ss1;
+            y0 = ss2;
+            x1 = ss1 + ss_size / 2 + 1;
+            y1 = ss2 + ss_size / 2 + 1;
+
+            // the second vectors (x1 and y1) are smaller about one from the first ones (x0 and y0)
+            Mul3Big3<ss_size/2 + 1, ss_size/2, ss_size*2>(x1, x0, y1, y0, result);
+        }
+        else
+        {
+            // ss_size is even
+            x0 = ss1;
+            y0 = ss2;
+            x1 = ss1 + ss_size / 2;
+            y1 = ss2 + ss_size / 2;
+
+            // all four vectors (x0 x1 y0 y1) are equal in size
+            Mul3Big3<ss_size/2, ss_size/2, ss_size*2>(x1, x0, y1, y0, result);
+        }
+    }
+
+
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4717)
+//warning C4717: recursive on all control paths, function will cause runtime stack overflow
+//we have the stop point in Mul3Big2() method
+#endif
+
+
+    /*!
+        an auxiliary method for calculating the Karatsuba multiplication
+
+            x = x1*B^m + x0
+            y = y1*B^m + y0
+
+            first_size  - is the size of vectors: x0 and y0
+            second_size - is the size of vectors: x1 and y1 (can be either equal first_size or smaller about one from first_size)
+
+            x*y = (x1*B^m + x0)(y1*B^m + y0) = z2*B^(2m) + z1*B^m + z0
+              where
+               z0 = x0*y0
+               z2 = x1*y1
+               z1 = (x1 + x0)*(y1 + y0) - z2 - z0
+    */
+    template<uint first_size, uint second_size, uint result_size>
+    void Mul3Big3(const uint * x1, const uint * x0, const uint * y1, const uint * y0, uint * result)
+    {
+    uint i, c, xc, yc;
+
+        UInt<first_size>   temp, temp2;
+        UInt<first_size*3> z1;
+
+        // z0 and z2 we store directly in the result (we don't use any temporary variables)
+        Mul3Big2<first_size>(x0, y0, result);                  // z0
+        Mul3Big2<second_size>(x1, y1, result+first_size*2);    // z2
+
+        // now we calculate z1
+        // temp  = (x0 + x1)
+        // temp2 = (y0 + y1)
+        // we're using temp and temp2 with UInt<first_size>, although there can be a carry but
+        // we simple remember it in xc and yc (xc and yc can be either 0 or 1),
+        // and (x0 + x1)*(y0 + y1) we calculate in this way (schoolbook algorithm):
+        //
+        //                 xc     |     temp
+        //                 yc     |     temp2
+        //               --------------------
+        //               (temp    *   temp2)
+        //               xc*temp2 |
+        //               yc*temp  |
+        //       xc*yc |
+        //       ----------     z1     --------
+        //
+        // and the result is never larger in size than 3*first_size
+
+        xc = AddVector(x0, x1, first_size, second_size, temp.table);
+        yc = AddVector(y0, y1, first_size, second_size, temp2.table);
+
+        Mul3Big2<first_size>(temp.table, temp2.table, z1.table);
+
+        // clearing the rest of z1
+        for(i=first_size*2 ; i<first_size*3 ; ++i)
+            z1.table[i] = 0;
+
+
+        if( xc )
+        {
+            c = AddVector(z1.table+first_size, temp2.table, first_size*3-first_size, first_size, z1.table+first_size);
+            TTMATH_ASSERT( c==0 )
+        }
+
+        if( yc )
+        {
+            c = AddVector(z1.table+first_size, temp.table, first_size*3-first_size, first_size, z1.table+first_size);
+            TTMATH_ASSERT( c==0 )
+        }
+
+
+        if( xc && yc )
+        {
+            for( i=first_size*2 ; i<first_size*3 ; ++i )
+                if( ++z1.table[i] != 0 )
+                    break;  // break if there was no carry
+        }
+
+        // z1 = z1 - z2
+        c = SubVector(z1.table, result+first_size*2, first_size*3, second_size*2, z1.table);
+        TTMATH_ASSERT(c==0)
+
+        // z1 = z1 - z0
+        c = SubVector(z1.table, result, first_size*3, first_size*2, z1.table);
+        TTMATH_ASSERT(c==0)
+
+        // here we've calculated the z1
+        // now we're adding it to the result
+
+        if( first_size > second_size )
+        {
+            uint z1_size = result_size - first_size;
+            TTMATH_ASSERT( z1_size <= first_size*3 )
+
+            for(i=z1_size ; i<first_size*3 ; ++i)
+                TTMATH_ASSERT( z1.table[i] == 0 )
+                ;
+
+            c = AddVector(result+first_size, z1.table, result_size-first_size, z1_size, result+first_size);
+            TTMATH_ASSERT(c==0)
+        }
+        else
+        {
+            c = AddVector(result+first_size, z1.table, result_size-first_size, first_size*3, result+first_size);
+            TTMATH_ASSERT(c==0)
+        }
+    }
+
+
+#ifdef _MSC_VER
+#pragma warning (default : 4717)
+#endif
+
+
+public:
+
+
+    /*!
+        multiplication this = this * ss2
+    */
+    uint MulFastest(const UInt<value_size> & ss2)
+    {
+    UInt<value_size*2> result;
+    uint i, c = 0;
+
+        MulFastestBig(ss2, result);
+
+        // copying result
+        for(i=0 ; i<value_size ; ++i)
+            table[i] = result.table[i];
+
+        // testing carry
+        for( ; i<value_size*2 ; ++i)
+            if( result.table[i] != 0 )
+            {
+                c = 1;
+                break;
+            }
+
+        TTMATH_LOGC("UInt::MulFastest", c)
+
+    return c;
+    }
+
+
+    /*!
+        multiplication result = this * ss2
+
+        this method is trying to select the fastest algorithm
+        (in the future this method can be improved)
+    */
+    void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
+    {
+        if( value_size < TTMATH_USE_KARATSUBA_MULTIPLICATION_FROM_SIZE )
+            return Mul2Big(ss2, result);
+
+        uint x1size  = value_size, x2size  = value_size;
+        uint x1start = 0,          x2start = 0;
+
+        for(x1size=value_size ; x1size>0 && table[x1size-1]==0 ; --x1size);
+        for(x2size=value_size ; x2size>0 && ss2.table[x2size-1]==0 ; --x2size);
+
+        if( x1size==0 || x2size==0 )
+        {
+            // either 'this' or 'ss2' is equal zero - the result is zero too
+            result.SetZero();
+            return;
+        }
+
+        for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
+        for(x2start=0 ; x2start<x2size && ss2.table[x2start]==0 ; ++x2start);
+
+        uint distancex1 = x1size - x1start;
+        uint distancex2 = x2size - x2start;
+
+        if( distancex1 < 3 || distancex2 < 3 )
+            // either 'this' or 'ss2' have only 2 (or 1) items different from zero (side by side)
+            // (this condition in the future can be improved)
+            return Mul2Big3<value_size>(table, ss2.table, result, x1start, x1size, x2start, x2size);
+
+
+        // Karatsuba multiplication
+        Mul3Big(ss2, result);
+
+        TTMATH_LOG("UInt::MulFastestBig")
+    }
+
+
+    /*!
+     *
+     * Division
+     *
+     *
+    */
+
+public:
+
+
+    /*!
+        division by one unsigned word
+
+        returns 1 when divisor is zero
+    */
+    uint DivInt(uint divisor, uint * remainder = 0)
+    {
+        if( divisor == 0 )
+        {
+            if( remainder )
+                *remainder = 0; // this is for convenience, without it the compiler can report that 'remainder' is uninitialized
+
+            TTMATH_LOG("UInt::DivInt")
+
+        return 1;
+        }
+
+        if( divisor == 1 )
+        {
+            if( remainder )
+                *remainder = 0;
+
+            TTMATH_LOG("UInt::DivInt")
+
+        return 0;
+        }
+
+        UInt<value_size> dividend(*this);
+        SetZero();
+
+        sint i;  // i must be with a sign
+        uint r = 0;
+
+        // we're looking for the last word in ss1
+        for(i=value_size-1 ; i>0 && dividend.table[i]==0 ; --i);
+
+        for( ; i>=0 ; --i)
+            DivTwoWords(r, dividend.table[i], divisor, &table[i], &r);
+
+        if( remainder )
+            *remainder = r;
+
+        TTMATH_LOG("UInt::DivInt")
+
+    return 0;
+    }
+
+    uint DivInt(uint divisor, uint & remainder)
+    {
+        return DivInt(divisor, &remainder);
+    }
+
+
+
+    /*!
+        division this = this / ss2
+
+        return values:
+             0 - ok
+             1 - division by zero
+            'this' will be the quotient
+            'remainder' - remainder
+    */
+    uint Div(   const UInt<value_size> & divisor,
+                UInt<value_size> * remainder = 0,
+                uint algorithm = 3)
+    {
+        switch( algorithm )
+        {
+        case 1:
+            return Div1(divisor, remainder);
+
+        case 2:
+            return Div2(divisor, remainder);
+
+        case 3:
+        default:
+            return Div3(divisor, remainder);
+        }
+    }
+
+    uint Div(const UInt<value_size> & divisor, UInt<value_size> & remainder, uint algorithm = 3)
+    {
+        return Div(divisor, &remainder, algorithm);
+    }
+
+
+
+private:
+
+    /*!
+        return values:
+        0 - none has to be done
+        1 - division by zero
+        2 - division should be made
+    */
+    uint Div_StandardTest(  const UInt<value_size> & v,
+                            uint & m, uint & n,
+                            UInt<value_size> * remainder = 0)
+    {
+        switch( Div_CalculatingSize(v, m, n) )
+        {
+        case 4: // 'this' is equal v
+            if( remainder )
+                remainder->SetZero();
+
+            SetOne();
+            TTMATH_LOG("UInt::Div_StandardTest")
+            return 0;
+
+        case 3: // 'this' is smaller than v
+            if( remainder )
+                *remainder = *this;
+
+            SetZero();
+            TTMATH_LOG("UInt::Div_StandardTest")
+            return 0;
+
+        case 2: // 'this' is zero
+            if( remainder )
+                remainder->SetZero();
+
+            SetZero();
+            TTMATH_LOG("UInt::Div_StandardTest")
+            return 0;
+
+        case 1: // v is zero
+            TTMATH_LOG("UInt::Div_StandardTest")
+            return 1;
+        }
+
+        TTMATH_LOG("UInt::Div_StandardTest")
+
+    return 2;
+    }
+
+
+
+    /*!
+        return values:
+        0 - ok
+            'm' - is the index (from 0) of last non-zero word in table ('this')
+            'n' - is the index (from 0) of last non-zero word in v.table
+        1 - v is zero
+        2 - 'this' is zero
+        3 - 'this' is smaller than v
+        4 - 'this' is equal v
+
+        if the return value is different than zero the 'm' and 'n' are undefined
+    */
+    uint Div_CalculatingSize(const UInt<value_size> & v, uint & m, uint & n)
+    {
+        m = n = value_size-1;
+
+        for( ; n!=0 && v.table[n]==0 ; --n);
+
+        if( n==0 && v.table[n]==0 )
+            return 1;
+
+        for( ; m!=0 && table[m]==0 ; --m);
+
+        if( m==0 && table[m]==0 )
+            return 2;
+
+        if( m < n )
+            return 3;
+        else
+        if( m == n )
+        {
+            uint i;
+            for(i = n ; i!=0 && table[i]==v.table[i] ; --i);
+
+            if( table[i] < v.table[i] )
+                return 3;
+            else
+            if (table[i] == v.table[i] )
+                return 4;
+        }
+
+    return 0;
+    }
+
+
+public:
+
+    /*!
+        the first division algorithm
+        radix 2
+    */
+    uint Div1(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
+    {
+    uint m,n, test;
+
+        test = Div_StandardTest(divisor, m, n, remainder);
+        if( test < 2 )
+            return test;
+
+        if( !remainder )
+        {
+            UInt<value_size> rem;
+
+        return Div1_Calculate(divisor, rem);
+        }
+
+    return Div1_Calculate(divisor, *remainder);
+    }
+
+
+private:
+
+
+    uint Div1_Calculate(const UInt<value_size> & divisor, UInt<value_size> & rest)
+    {
+    TTMATH_REFERENCE_ASSERT( divisor )
+
+    sint loop;
+    sint c;
+
+        rest.SetZero();
+        loop = value_size * TTMATH_BITS_PER_UINT;
+        c = 0;
+
+
+    div_a:
+        c = Rcl(1, c);
+        c = rest.Add(rest,c);
+        c = rest.Sub(divisor,c);
+
+        c = !c;
+
+        if(!c)
+            goto div_d;
+
+
+    div_b:
+        --loop;
+        if(loop)
+            goto div_a;
+
+        c = Rcl(1, c);
+        TTMATH_LOG("UInt::Div1_Calculate")
+        return 0;
+
+
+    div_c:
+        c = Rcl(1, c);
+        c = rest.Add(rest,c);
+        c = rest.Add(divisor);
+
+        if(c)
+            goto div_b;
+
+
+    div_d:
+        --loop;
+        if(loop)
+            goto div_c;
+
+        c = Rcl(1, c);
+        c = rest.Add(divisor);
+
+        TTMATH_LOG("UInt::Div1_Calculate")
+
+    return 0;
+    }
+
+
+public:
+
+
+    /*!
+        the second division algorithm
+
+        return values:
+            0 - ok
+            1 - division by zero
+    */
+    uint Div2(const UInt<value_size> & divisor, UInt<value_size> * remainder = 0)
+    {
+        TTMATH_REFERENCE_ASSERT( divisor )
+
+        uint bits_diff;
+        uint status = Div2_Calculate(divisor, remainder, bits_diff);
+        if( status < 2 )
+            return status;
+
+        if( CmpBiggerEqual(divisor) )
+        {
+            Div2(divisor, remainder);
+            SetBit(bits_diff);
+        }
+        else
+        {
+            if( remainder )
+                *remainder = *this;
+
+            SetZero();
+            SetBit(bits_diff);
+        }
+
+        TTMATH_LOG("UInt::Div2")
+
+    return 0;
+    }
+
+
+    uint Div2(const UInt<value_size> & divisor, UInt<value_size> & remainder)
+    {
+        return Div2(divisor, &remainder);
+    }
+
+
+private:
+
+    /*!
+        return values:
+            0 - we've calculated the division
+            1 - division by zero
+            2 - we have to still calculate
+
+    */
+    uint Div2_Calculate(const UInt<value_size> & divisor, UInt<value_size> * remainder,
+                                                            uint & bits_diff)
+    {
+    uint table_id, index;
+    uint divisor_table_id, divisor_index;
+
+        uint status = Div2_FindLeadingBitsAndCheck( divisor, remainder,
+                                                    table_id, index,
+                                                    divisor_table_id, divisor_index);
+
+        if( status < 2 )
+        {
+            TTMATH_LOG("UInt::Div2_Calculate")
+            return status;
+        }
+
+        // here we know that 'this' is greater than divisor
+        // then 'index' is greater or equal 'divisor_index'
+        bits_diff = index - divisor_index;
+
+        UInt<value_size> divisor_copy(divisor);
+        divisor_copy.Rcl(bits_diff, 0);
+
+        if( CmpSmaller(divisor_copy, table_id) )
+        {
+            divisor_copy.Rcr(1);
+            --bits_diff;
+        }
+
+        Sub(divisor_copy, 0);
+
+        TTMATH_LOG("UInt::Div2_Calculate")
+
+    return 2;
+    }
+
+
+    /*!
+        return values:
+            0 - we've calculated the division
+            1 - division by zero
+            2 - we have to still calculate
+    */
+    uint Div2_FindLeadingBitsAndCheck(  const UInt<value_size> & divisor,
+                                        UInt<value_size> * remainder,
+                                        uint & table_id, uint & index,
+                                        uint & divisor_table_id, uint & divisor_index)
+    {
+        if( !divisor.FindLeadingBit(divisor_table_id, divisor_index) )
+        {
+            // division by zero
+            TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+            return 1;
+        }
+
+        if( !FindLeadingBit(table_id, index) )
+        {
+            // zero is divided by something
+
+            SetZero();
+
+            if( remainder )
+                remainder->SetZero();
+
+            TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+
+        return 0;
+        }
+
+        divisor_index += divisor_table_id * TTMATH_BITS_PER_UINT;
+        index         += table_id         * TTMATH_BITS_PER_UINT;
+
+        if( divisor_table_id == 0 )
+        {
+            // dividor has only one 32-bit word
+
+            uint r;
+            DivInt(divisor.table[0], &r);
+
+            if( remainder )
+            {
+                remainder->SetZero();
+                remainder->table[0] = r;
+            }
+
+            TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+
+        return 0;
+        }
+
+
+        if( Div2_DivisorGreaterOrEqual( divisor, remainder,
+                                        table_id, index,
+                                        divisor_index) )
+        {
+            TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+            return 0;
+        }
+
+
+        TTMATH_LOG("UInt::Div2_FindLeadingBitsAndCheck")
+
+    return 2;
+    }
+
+
+    /*!
+        return values:
+            true if divisor is equal or greater than 'this'
+    */
+    bool Div2_DivisorGreaterOrEqual(    const UInt<value_size> & divisor,
+                                        UInt<value_size> * remainder,
+                                        uint table_id, uint index,
+                                        uint divisor_index  )
+    {
+        if( divisor_index > index )
+        {
+            // divisor is greater than this
+
+            if( remainder )
+                *remainder = *this;
+
+            SetZero();
+
+            TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
+
+        return true;
+        }
+
+        if( divisor_index == index )
+        {
+            // table_id == divisor_table_id as well
+
+            uint i;
+            for(i = table_id ; i!=0 && table[i]==divisor.table[i] ; --i);
+
+            if( table[i] < divisor.table[i] )
+            {
+                // divisor is greater than 'this'
+
+                if( remainder )
+                    *remainder = *this;
+
+                SetZero();
+
+                TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
+
+            return true;
+            }
+            else
+            if( table[i] == divisor.table[i] )
+            {
+                // divisor is equal 'this'
+
+                if( remainder )
+                    remainder->SetZero();
+
+                SetOne();
+
+                TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
+
+            return true;
+            }
+        }
+
+        TTMATH_LOG("UInt::Div2_DivisorGreaterOrEqual")
+
+    return false;
+    }
+
+
+public:
+
+    /*!
+        the third division algorithm
+
+        this algorithm is described in the following book:
+            "The art of computer programming 2" (4.3.1 page 272)
+            Donald E. Knuth
+    */
+    uint Div3(const UInt<value_size> & v, UInt<value_size> * remainder = 0)
+    {
+    TTMATH_REFERENCE_ASSERT( v )
+
+    uint m,n, test;
+
+        test = Div_StandardTest(v, m, n, remainder);
+        if( test < 2 )
+            return test;
+
+        if( n == 0 )
+        {
+            uint r;
+            DivInt( v.table[0], &r );
+
+            if( remainder )
+            {
+                remainder->SetZero();
+                remainder->table[0] = r;
+            }
+
+            TTMATH_LOG("UInt::Div3")
+
+        return 0;
+        }
+
+
+        // we can only use the third division algorithm when
+        // the divisor is greater or equal 2^32 (has more than one 32-bit word)
+        ++m;
+        ++n;
+        m = m - n;
+        Div3_Division(v, remainder, m, n);
+
+        TTMATH_LOG("UInt::Div3")
+
+    return 0;
+    }
+
+
+
+private:
+
+
+    void Div3_Division(UInt<value_size> v, UInt<value_size> * remainder, uint m, uint n)
+    {
+    TTMATH_ASSERT( n>=2 )
+
+    UInt<value_size+1> uu, vv;
+    UInt<value_size> q;
+    uint d, u_value_size, u0, u1, u2, v1, v0, j=m;
+
+        u_value_size = Div3_Normalize(v, n, d);
+
+        if( j+n == value_size )
+            u2 = u_value_size;
+        else
+            u2 = table[j+n];
+
+        Div3_MakeBiggerV(v, vv);
+
+        for(uint i = j+1 ; i<value_size ; ++i)
+            q.table[i] = 0;
+
+        while( true )
+        {
+            u1 = table[j+n-1];
+            u0 = table[j+n-2];
+            v1 = v.table[n-1];
+            v0 = v.table[n-2];
+
+            uint qp = Div3_Calculate(u2,u1,u0, v1,v0);
+
+            Div3_MakeNewU(uu, j, n, u2);
+            Div3_MultiplySubtract(uu, vv, qp);
+            Div3_CopyNewU(uu, j, n);
+
+            q.table[j] = qp;
+
+            // the next loop
+            if( j-- == 0 )
+                break;
+
+            u2 = table[j+n];
+        }
+
+        if( remainder )
+            Div3_Unnormalize(remainder, n, d);
+
+    *this = q;
+
+    TTMATH_LOG("UInt::Div3_Division")
+    }
+
+
+    void Div3_MakeNewU(UInt<value_size+1> & uu, uint j, uint n, uint u_max)
+    {
+    uint i;
+
+        for(i=0 ; i<n ; ++i, ++j)
+            uu.table[i] = table[j];
+
+        // 'n' is from <1..value_size> so and 'i' is from <0..value_size>
+        // then table[i] is always correct (look at the declaration of 'uu')
+        uu.table[i] = u_max;
+
+        for( ++i ; i<value_size+1 ; ++i)
+            uu.table[i] = 0;
+
+        TTMATH_LOG("UInt::Div3_MakeNewU")
+    }
+
+
+    void Div3_CopyNewU(const UInt<value_size+1> & uu, uint j, uint n)
+    {
+    uint i;
+
+        for(i=0 ; i<n ; ++i)
+            table[i+j] = uu.table[i];
+
+        if( i+j < value_size )
+            table[i+j] = uu.table[i];
+
+        TTMATH_LOG("UInt::Div3_CopyNewU")
+    }
+
+
+    /*!
+        we're making the new 'vv'
+        the value is actually the same but the 'table' is bigger (value_size+1)
+    */
+    void Div3_MakeBiggerV(const UInt<value_size> & v, UInt<value_size+1> & vv)
+    {
+        for(uint i=0 ; i<value_size ; ++i)
+            vv.table[i] = v.table[i];
+
+        vv.table[value_size] = 0;
+
+        TTMATH_LOG("UInt::Div3_MakeBiggerV")
+    }
+
+
+    /*!
+        we're moving all bits from 'v' into the left side of the n-1 word
+        (the highest bit at v.table[n-1] will be equal one,
+        the bits from 'this' we're moving the same times as 'v')
+
+        return values:
+          d - how many times we've moved
+          return - the next-left value from 'this' (that after table[value_size-1])
+    */
+    uint Div3_Normalize(UInt<value_size> & v, uint n, uint & d)
+    {
+        // v.table[n-1] is != 0
+
+        uint bit  = (uint)FindLeadingBitInWord(v.table[n-1]);
+        uint move = (TTMATH_BITS_PER_UINT - bit - 1);
+        uint res  = table[value_size-1];
+        d         = move;
+
+        if( move > 0 )
+        {
+            v.Rcl(move, 0);
+            Rcl(move, 0);
+            res = res >> (bit + 1);
+        }
+        else
+        {
+            res = 0;
+        }
+
+        TTMATH_LOG("UInt::Div3_Normalize")
+
+    return res;
+    }
+
+
+    void Div3_Unnormalize(UInt<value_size> * remainder, uint n, uint d)
+    {
+        for(uint i=n ; i<value_size ; ++i)
+            table[i] = 0;
+
+        Rcr(d,0);
+
+        *remainder = *this;
+
+        TTMATH_LOG("UInt::Div3_Unnormalize")
+    }
+
+
+    uint Div3_Calculate(uint u2, uint u1, uint u0, uint v1, uint v0)
+    {
+    UInt<2> u_temp;
+    uint rp;
+    bool next_test;
+
+        TTMATH_ASSERT( v1 != 0 )
+
+        u_temp.table[1] = u2;
+        u_temp.table[0] = u1;
+        u_temp.DivInt(v1, &rp);
+
+        TTMATH_ASSERT( u_temp.table[1]==0 || u_temp.table[1]==1 )
+
+        do
+        {
+            bool decrease = false;
+
+            if( u_temp.table[1] == 1 )
+                decrease = true;
+            else
+            {
+                UInt<2> temp1, temp2;
+
+                UInt<2>::MulTwoWords(u_temp.table[0], v0, temp1.table+1, temp1.table);
+                temp2.table[1] = rp;
+                temp2.table[0] = u0;
+
+                if( temp1 > temp2 )
+                    decrease = true;
+            }
+
+            next_test = false;
+
+            if( decrease )
+            {
+                u_temp.SubOne();
+
+                rp += v1;
+
+                if( rp >= v1 ) // it means that there wasn't a carry (r<b from the book)
+                    next_test = true;
+            }
+        }
+        while( next_test );
+
+        TTMATH_LOG("UInt::Div3_Calculate")
+
+    return u_temp.table[0];
+    }
+
+
+
+    void Div3_MultiplySubtract( UInt<value_size+1> & uu,
+                                const UInt<value_size+1> & vv, uint & qp)
+    {
+        // D4 (in the book)
+
+        UInt<value_size+1> vv_temp(vv);
+        vv_temp.MulInt(qp);
+
+        if( uu.Sub(vv_temp) )
+        {
+            // there was a carry
+
+            //
+            // !!! this part of code was not tested
+            //
+
+            --qp;
+            uu.Add(vv);
+
+            // can be a carry from this additions but it should be ignored
+            // because it cancels with the borrow from uu.Sub(vv_temp)
+        }
+
+        TTMATH_LOG("UInt::Div3_MultiplySubtract")
+    }
+
+
+
+
+
+
+public:
+
+
+    /*!
+        power this = this ^ pow
+        binary algorithm (r-to-l)
+
+        return values:
+        0 - ok
+        1 - carry
+        2 - incorrect argument (0^0)
+    */
+    uint Pow(UInt<value_size> pow)
+    {
+        if(pow.IsZero() && IsZero())
+            // we don't define zero^zero
+            return 2;
+
+        UInt<value_size> start(*this), start_temp;
+        UInt<value_size> result;
+        result.SetOne();
+        uint c = 0;
+
+        while( !c )
+        {
+            if( pow.table[0] & 1 )
+                c += result.Mul(start);
+
+            pow.Rcr2_one(0);
+            if( pow.IsZero() )
+                break;
+
+            start_temp = start;
+            // in the second Mul algorithm we can use start.Mul(start) directly (there is no TTMATH_ASSERT_REFERENCE there)
+            c += start.Mul(start_temp);
+        }
+
+        *this = result;
+
+        TTMATH_LOGC("UInt::Pow(UInt<>)", c)
+
+    return (c==0)? 0 : 1;
+    }
+
+
+    /*!
+        square root
+        e.g. Sqrt(9) = 3
+        ('digit-by-digit' algorithm)
+    */
+    void Sqrt()
+    {
+    UInt<value_size> bit, temp;
+
+        if( IsZero() )
+            return;
+
+        UInt<value_size> value(*this);
+
+        SetZero();
+        bit.SetZero();
+        bit.table[value_size-1] = (TTMATH_UINT_HIGHEST_BIT >> 1);
+
+        while( bit > value )
+            bit.Rcr(2);
+
+        while( !bit.IsZero() )
+        {
+            temp = *this;
+            temp.Add(bit);
+
+            if( value >= temp )
+            {
+                value.Sub(temp);
+                Rcr(1);
+                Add(bit);
+            }
+            else
+            {
+                Rcr(1);
+            }
+
+            bit.Rcr(2);
+        }
+
+        TTMATH_LOG("UInt::Sqrt")
+    }
+
+
+
+    /*!
+        this method sets n first bits to value zero
+
+        For example:
+        let n=2 then if there's a value 111 (bin) there'll be '100' (bin)
+    */
+    void ClearFirstBits(uint n)
+    {
+        if( n >= value_size*TTMATH_BITS_PER_UINT )
+        {
+            SetZero();
+            TTMATH_LOG("UInt::ClearFirstBits")
+            return;
+        }
+
+        uint * p = table;
+
+        // first we're clearing the whole words
+        while( n >= TTMATH_BITS_PER_UINT )
+        {
+            *p++ = 0;
+            n   -= TTMATH_BITS_PER_UINT;
+        }
+
+        if( n == 0 )
+        {
+            TTMATH_LOG("UInt::ClearFirstBits")
+            return;
+        }
+
+        // and then we're clearing one word which has left
+        // mask -- all bits are set to one
+        uint mask = TTMATH_UINT_MAX_VALUE;
+
+        mask = mask << n;
+
+        (*p) &= mask;
+
+        TTMATH_LOG("UInt::ClearFirstBits")
+    }
+
+
+    /*!
+        this method returns true if the highest bit of the value is set
+    */
+    bool IsTheHighestBitSet() const
+    {
+        return (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) != 0;
+    }
+
+
+    /*!
+        this method returns true if the lowest bit of the value is set
+    */
+    bool IsTheLowestBitSet() const
+    {
+        return (*table & 1) != 0;
+    }
+
+
+    /*!
+        this method returns true if the value is equal zero
+    */
+    bool IsZero() const
+    {
+        for(uint i=0 ; i<value_size ; ++i)
+            if(table[i] != 0)
+                return false;
+
+    return true;
+    }
+
+
+    /*!
+        returning true if first 'bits' bits are equal zero
+    */
+    bool AreFirstBitsZero(uint bits) const
+    {
+        TTMATH_ASSERT( bits <= value_size * TTMATH_BITS_PER_UINT )
+
+        uint index = bits / TTMATH_BITS_PER_UINT;
+        uint rest  = bits % TTMATH_BITS_PER_UINT;
+        uint i;
+
+        for(i=0 ; i<index ; ++i)
+            if(table[i] != 0 )
+                return false;
+
+        if( rest == 0 )
+            return true;
+
+        uint mask = TTMATH_UINT_MAX_VALUE >> (TTMATH_BITS_PER_UINT - rest);
+
+    return (table[i] & mask) == 0;
+    }
+
+
+
+    /*!
+    *
+    *   conversion methods
+    *
+    */
+
+
+
+    /*!
+        this method converts an UInt<another_size> type to this class
+
+        this operation has mainly sense if the value from p is
+        equal or smaller than that one which is returned from UInt<value_size>::SetMax()
+
+        it returns a carry if the value 'p' is too big
+    */
+    template<uint argument_size>
+    uint FromUInt(const UInt<argument_size> & p)
+    {
+        uint min_size = (value_size < argument_size)? value_size : argument_size;
+        uint i;
+
+        for(i=0 ; i<min_size ; ++i)
+            table[i] = p.table[i];
+
+
+        if( value_size > argument_size )
+        {
+            // 'this' is longer than 'p'
+
+            for( ; i<value_size ; ++i)
+                table[i] = 0;
+        }
+        else
+        {
+            for( ; i<argument_size ; ++i)
+                if( p.table[i] != 0 )
+                {
+                    TTMATH_LOGC("UInt::FromUInt(UInt<>)", 1)
+                    return 1;
+                }
+        }
+
+        TTMATH_LOGC("UInt::FromUInt(UInt<>)", 0)
+
+    return 0;
+    }
+
+
+    /*!
+        this method converts the uint type to this class
+    */
+    void FromUInt(uint value)
+    {
+        for(uint i=1 ; i<value_size ; ++i)
+            table[i] = 0;
+
+        table[0] = value;
+
+        TTMATH_LOG("UInt::FromUInt(uint)")
+    }
+
+
+    /*!
+        this operator converts an UInt<another_size> type to this class
+
+        it doesn't return a carry
+    */
+    template<uint argument_size>
+    UInt<value_size> & operator=(const UInt<argument_size> & p)
+    {
+        FromUInt(p);
+
+    return *this;
+    }
+
+
+    /*!
+        the assignment operator
+    */
+    UInt<value_size> & operator=(const UInt<value_size> & p)
+    {
+        for(uint i=0 ; i<value_size ; ++i)
+            table[i] = p.table[i];
+
+        TTMATH_LOG("UInt::operator=(UInt<>)")
+
+        return *this;
+    }
+
+
+    /*!
+        this method converts the uint type to this class
+    */
+    UInt<value_size> & operator=(uint i)
+    {
+        FromUInt(i);
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting the uint to this class
+    */
+    UInt(uint i)
+    {
+        FromUInt(i);
+    }
+
+
+    /*!
+        this method converts the sint type to this class
+
+        we provide operator(sint) and the constructor(sint) in order to allow
+        the programmer do that:
+            UInt<..> type = 10;
+
+        above "10" constant has the int type (signed int), if we don't give such
+        operators and constructors the compiler will not compile the program,
+        because it has to make a conversion and doesn't know into which type
+        (the UInt class has operator=(const char*), operator=(uint) etc.)
+    */
+    UInt<value_size> & operator=(sint i)
+    {
+        FromUInt(uint(i));
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting the sint to this class
+
+        look at the description of UInt::operator=(sint)
+    */
+    UInt(sint i)
+    {
+        FromUInt(uint(i));
+    }
+
+
+
+#ifdef TTMATH_PLATFORM64
+
+    /*!
+        in 64bit platforms we must define additional operators and contructors
+        in order to allow a user initializing the objects in this way:
+            UInt<...> type = 20;
+        or
+            UInt<...> type;
+            type = 30;
+
+        decimal constants such as 20, 30 etc. are integer literal of type int,
+        if the value is greater it can even be long int,
+        0 is an octal integer of type int
+        (ISO 14882 p2.13.1 Integer literals)
+    */
+
+    /*!
+        this operator converts the unsigned int type to this class
+
+        ***this operator is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    UInt<value_size> & operator=(unsigned int i)
+    {
+        FromUInt(uint(i));
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting the unsigned int to this class
+
+        ***this constructor is created only on a 64bit platform***
+        it takes one argument of 32bit
+    */
+    UInt(unsigned int i)
+    {
+        FromUInt(uint(i));
+    }
+
+
+    /*!
+        an operator for converting the signed int to this class
+
+        ***this constructor is created only on a 64bit platform***
+        it takes one argument of 32bit
+
+        look at the description of UInt::operator=(sint)
+    */
+    UInt<value_size> & operator=(signed int i)
+    {
+        FromUInt(uint(i));
+
+    return *this;
+    }
+
+
+    /*!
+        a constructor for converting the signed int to this class
+
+        ***this constructor is created only on a 64bit platform***
+        it takes one argument of 32bit
+
+        look at the description of UInt::operator=(sint)
+    */
+    UInt(signed int i)
+    {
+        FromUInt(uint(i));
+    }
+
+
+#endif
+
+
+
+
+
+    /*!
+        a constructor for converting a string to this class (with the base=10)
+    */
+    UInt(const char * s)
+    {
+        FromString(s);
+    }
+
+
+    /*!
+        a constructor for converting a string to this class (with the base=10)
+    */
+    UInt(const wchar_t * s)
+    {
+        FromString(s);
+    }
+
+
+    /*!
+        a constructor for converting a string to this class (with the base=10)
+    */
+    UInt(const std::string & s)
+    {
+        FromString( s.c_str() );
+    }
+
+
+    /*!
+        a constructor for converting a string to this class (with the base=10)
+    */
+    UInt(const std::wstring & s)
+    {
+        FromString( s.c_str() );
+    }
+
+
+    /*!
+        a default constructor
+
+        we don't clear the table
+    */
+    UInt()
+    {
+    // when macro TTMATH_DEBUG_LOG is defined
+    // we set special values to the table
+    // in order to be everywhere the same value of the UInt object
+    // without this it would be difficult to analyse the log file
+    #ifdef TTMATH_DEBUG_LOG
+        #ifdef TTMATH_PLATFORM32
+                for(uint i=0 ; i<value_size ; ++i)
+                    table[i] = 0xc1c1c1c1;
+        #else
+                for(uint i=0 ; i<value_size ; ++i)
+                    table[i] = 0xc1c1c1c1c1c1c1c1;
+        #endif
+    #endif
+    }
+
+
+    /*!
+        a copy constructor
+    */
+    UInt(const UInt<value_size> & u)
+    {
+        for(uint i=0 ; i<value_size ; ++i)
+            table[i] = u.table[i];
+
+        TTMATH_LOG("UInt::UInt(UInt<>)")
+    }
+
+
+
+    /*!
+        a template for producting constructors for copying from another types
+    */
+    template<uint argument_size>
+    UInt(const UInt<argument_size> & u)
+    {
+        // look that 'size' we still set as 'value_size' and not as u.value_size
+        FromUInt(u);
+    }
+
+
+
+
+    /*!
+        a destructor
+    */
+    ~UInt()
+    {
+    }
+
+
+    /*!
+        this method returns the lowest value from table
+
+        we must be sure when we using this method whether the value
+        will hold in an uint type or not (the rest value from the table must be zero)
+    */
+    uint ToUInt() const
+    {
+        return table[0];
+    }
+
+
+private:
+
+    /*!
+        an auxiliary method for converting to a string
+    */
+    template<class string_type>
+    void ToStringBase(string_type & result, uint b = 10) const
+    {
+    UInt<value_size> temp( *this );
+    char character;
+    uint rem;
+
+        result.clear();
+
+        if( b<2 || b>16 )
+            return;
+
+        do
+        {
+            temp.DivInt(b, &rem);
+            character = static_cast<char>( Misc::DigitToChar(rem) );
+            result.insert(result.begin(), character);
+        }
+        while( !temp.IsZero() );
+
+    return;
+    }
+
+
+public:
+
+    /*!
+        this method converts the value to a string with a base equal 'b'
+    */
+    void ToString(std::string & result, uint b = 10) const
+    {
+        return ToStringBase(result, b);
+    }
+
+    void ToString(std::wstring & result, uint b = 10) const
+    {
+        return ToStringBase(result, b);
+    }
+
+    std::string ToString(uint b = 10) const
+    {
+        std::string result;
+        ToStringBase(result, b);
+
+    return result;
+    }
+
+    std::wstring ToWString(uint b = 10) const
+    {
+        std::wstring result;
+        ToStringBase(result, b);
+
+    return result;
+    }
+
+
+private:
+
+    /*!
+        an auxiliary method for converting from a string
+    */
+    template<class char_type>
+    uint FromStringBase(const char_type * s, uint b = 10, const char_type ** after_source = 0, bool * value_read = 0)
+    {
+    UInt<value_size> base( b );
+    UInt<value_size> temp;
+    sint z;
+    uint c = 0;
+
+        SetZero();
+        temp.SetZero();
+        Misc::SkipWhiteCharacters(s);
+
+        if( after_source )
+            *after_source = s;
+
+        if( value_read )
+            *value_read = false;
+
+        if( b<2 || b>16 )
+            return 1;
+
+
+        for( ; (z=Misc::CharToDigit(*s, b)) != -1 ; ++s)
+        {
+            if( value_read )
+                *value_read = true;
+
+            if( c == 0 )
+            {
+                temp.table[0] = z;
+
+                c += Mul(base);
+                c += Add(temp);
+            }
+        }
+
+        if( after_source )
+            *after_source = s;
+
+        TTMATH_LOGC("UInt::FromString", c)
+
+    return (c==0)? 0 : 1;
+    }
+
+
+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
+
+        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
+
+        if the value from s is too large the rest digits will be skipped
+
+        after_source (if exists) is pointing at the end of the parsed string
+
+        value_read (if exists) tells whether something has actually been read (at least one digit)
+    */
+    uint FromString(const char * s, uint b = 10, const char ** after_source = 0, bool * value_read = 0)
+    {
+        return FromStringBase(s, b, after_source, value_read);
+    }
+
+
+    /*!
+        this method converts a string into its value
+    */
+    uint FromString(const wchar_t * s, uint b = 10, const wchar_t ** after_source = 0, bool * value_read = 0)
+    {
+        return FromStringBase(s, b, after_source, value_read);
+    }
+
+
+    /*!
+        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(), 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)
+    */
+    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)
+    */
+    UInt<value_size> & operator=(const char * s)
+    {
+        FromString(s);
+
+    return *this;
+    }
+
+
+    /*!
+        this operator converts a string into its value (with base = 10)
+    */
+    UInt<value_size> & operator=(const wchar_t * s)
+    {
+        FromString(s);
+
+    return *this;
+    }
+
+
+    /*!
+        this operator converts a string into its value (with base = 10)
+    */
+    UInt<value_size> & operator=(const std::string & s)
+    {
+        FromString( s.c_str() );
+
+    return *this;
+    }
+
+
+    /*!
+        this operator converts a string into its value (with base = 10)
+    */
+    UInt<value_size> & operator=(const std::wstring & s)
+    {
+        FromString( s.c_str() );
+
+    return *this;
+    }
+
+
+    /*!
+    *
+    *   methods for comparing
+    *
+    */
+
+
+    /*!
+        this method returns true if 'this' is smaller than 'l'
+
+        'index' is an index of the first word from will be the comparison performed
+        (note: we start the comparison from back - from the last word, when index is -1 /default/
+        it is automatically set into the last word)
+        I introduced it for some kind of optimization made in the second division algorithm (Div2)
+    */
+    bool CmpSmaller(const UInt<value_size> & l, sint index = -1) const
+    {
+    sint i;
+
+        if( index==-1 || index>=sint(value_size) )
+            i = value_size - 1;
+        else
+            i = index;
+
+
+        for( ; i>=0 ; --i)
+        {
+            if( table[i] != l.table[i] )
+                return table[i] < l.table[i];
+        }
+
+    // they're equal
+    return false;
+    }
+
+
+
+    /*!
+        this method returns true if 'this' is bigger than 'l'
+
+        'index' is an index of the first word from will be the comparison performed
+        (note: we start the comparison from back - from the last word, when index is -1 /default/
+        it is automatically set into the last word)
+
+        I introduced it for some kind of optimization made in the second division algorithm (Div2)
+    */
+    bool CmpBigger(const UInt<value_size> & l, sint index = -1) const
+    {
+    sint i;
+
+        if( index==-1 || index>=sint(value_size) )
+            i = value_size - 1;
+        else
+            i = index;
+
+
+        for( ; i>=0 ; --i)
+        {
+            if( table[i] != l.table[i] )
+                return table[i] > l.table[i];
+        }
+
+    // they're equal
+    return false;
+    }
+
+
+    /*!
+        this method returns true if 'this' is equal 'l'
+
+        'index' is an index of the first word from will be the comparison performed
+        (note: we start the comparison from back - from the last word, when index is -1 /default/
+        it is automatically set into the last word)
+    */
+    bool CmpEqual(const UInt<value_size> & l, sint index = -1) const
+    {
+    sint i;
+
+        if( index==-1 || index>=sint(value_size) )
+            i = value_size - 1;
+        else
+            i = index;
+
+
+        for( ; i>=0 ; --i)
+            if( table[i] != l.table[i] )
+                return false;
+
+    return true;
+    }
+
+
+
+    /*!
+        this method returns true if 'this' is smaller than or equal 'l'
+
+        'index' is an index of the first word from will be the comparison performed
+        (note: we start the comparison from back - from the last word, when index is -1 /default/
+        it is automatically set into the last word)
+    */
+    bool CmpSmallerEqual(const UInt<value_size> & l, sint index=-1) const
+    {
+    sint i;
+
+        if( index==-1 || index>=sint(value_size) )
+            i = value_size - 1;
+        else
+            i = index;
+
+
+        for( ; i>=0 ; --i)
+        {
+            if( table[i] != l.table[i] )
+                return table[i] < l.table[i];
+        }
+
+    // they're equal
+    return true;
+    }
+
+
+
+    /*!
+        this method returns true if 'this' is bigger than or equal 'l'
+
+        'index' is an index of the first word from will be the comparison performed
+        (note: we start the comparison from back - from the last word, when index is -1 /default/
+        it is automatically set into the last word)
+    */
+    bool CmpBiggerEqual(const UInt<value_size> & l, sint index=-1) const
+    {
+    sint i;
+
+        if( index==-1 || index>=sint(value_size) )
+            i = value_size - 1;
+        else
+            i = index;
+
+
+        for( ; i>=0 ; --i)
+        {
+            if( table[i] != l.table[i] )
+                return table[i] > l.table[i];
+        }
+
+    // they're equal
+    return true;
+    }
+
+
+    /*
+        operators for comparising
+    */
+
+    bool operator<(const UInt<value_size> & l) const
+    {
+        return CmpSmaller(l);
+    }
+
+
+    bool operator>(const UInt<value_size> & l) const
+    {
+        return CmpBigger(l);
+    }
+
+
+    bool operator==(const UInt<value_size> & l) const
+    {
+        return CmpEqual(l);
+    }
+
+
+    bool operator!=(const UInt<value_size> & l) const
+    {
+        return !operator==(l);
+    }
+
+
+    bool operator<=(const UInt<value_size> & l) const
+    {
+        return CmpSmallerEqual(l);
+    }
+
+    bool operator>=(const UInt<value_size> & l) const
+    {
+        return CmpBiggerEqual(l);
+    }
+
+
+    /*!
+    *
+    *   standard mathematical operators
+    *
+    */
+
+    UInt<value_size> operator-(const UInt<value_size> & p2) const
+    {
+    UInt<value_size> temp(*this);
+
+        temp.Sub(p2);
+
+    return temp;
+    }
+
+    UInt<value_size> & operator-=(const UInt<value_size> & p2)
+    {
+        Sub(p2);
+
+    return *this;
+    }
+
+    UInt<value_size> operator+(const UInt<value_size> & p2) const
+    {
+    UInt<value_size> temp(*this);
+
+        temp.Add(p2);
+
+    return temp;
+    }
+
+    UInt<value_size> & operator+=(const UInt<value_size> & p2)
+    {
+        Add(p2);
+
+    return *this;
+    }
+
+
+    UInt<value_size> operator*(const UInt<value_size> & p2) const
+    {
+    UInt<value_size> temp(*this);
+
+        temp.Mul(p2);
+
+    return temp;
+    }
+
+
+    UInt<value_size> & operator*=(const UInt<value_size> & p2)
+    {
+        Mul(p2);
+
+    return *this;
+    }
+
+
+    UInt<value_size> operator/(const UInt<value_size> & p2) const
+    {
+    UInt<value_size> temp(*this);
+
+        temp.Div(p2);
+
+    return temp;
+    }
+
+
+    UInt<value_size> & operator/=(const UInt<value_size> & p2)
+    {
+        Div(p2);
+
+    return *this;
+    }
+
+
+    UInt<value_size> operator%(const UInt<value_size> & p2) const
+    {
+    UInt<value_size> temp(*this);
+    UInt<value_size> remainder;
+
+        temp.Div( p2, remainder );
+
+    return remainder;
+    }
+
+
+    UInt<value_size> & operator%=(const UInt<value_size> & p2)
+    {
+    UInt<value_size> temp(*this);
+    UInt<value_size> remainder;
+
+        temp.Div( p2, remainder );
+
+        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--()
+    {
+        SubOne();
+
+    return *this;
+    }
+
+
+    UInt<value_size> operator--(int)
+    {
+    UInt<value_size> temp( *this );
+
+        SubOne();
+
+    return temp;
+    }
+
+
+    UInt<value_size> operator>>(int move)
+    {
+    UInt<value_size> temp( *this );
+
+        temp.Rcr(move);
+
+    return temp;
+    }
+
+
+    UInt<value_size> & operator>>=(int move)
+    {
+        Rcr(move);
+
+    return *this;
+    }
+
+
+    UInt<value_size> operator<<(int move)
+    {
+    UInt<value_size> temp( *this );
+
+        temp.Rcl(move);
+
+    return temp;
+    }
+
+
+    UInt<value_size> & operator<<=(int move)
+    {
+        Rcl(move);
+
+    return *this;
+    }
+
+
+    /*!
+    *
+    *   input/output operators for standard streams
+    *
+    *   (they are very simple, in the future they should be changed)
+    *
+    */
+
+
+private:
+
+
+    /*!
+        an auxiliary method for outputing to standard streams
+    */
+    template<class ostream_type, class string_type>
+    static ostream_type & OutputToStream(ostream_type & s, const UInt<value_size> & l)
+    {
+    string_type ss;
+
+        l.ToString(ss);
+        s << ss;
+
+    return s;
+    }
+
+
+public:
+
+
+    /*!
+        output to standard streams
+    */
+    friend std::ostream & operator<<(std::ostream & s, const UInt<value_size> & l)
+    {
+        return OutputToStream<std::ostream, std::string>(s, l);
+    }
+
+
+
+
+private:
+
+    /*!
+        an auxiliary method for reading from standard streams
+    */
+    template<class istream_type, class string_type, class char_type>
+    static istream_type & InputFromStream(istream_type & s, UInt<value_size> & l)
+    {
+    string_type ss;
+
+    // char or wchar_t for operator>>
+    char_type z;
+
+        // operator>> omits white characters if they're set for ommiting
+        s >> z;
+
+        // we're reading only digits (base=10)
+        while( s.good() && Misc::CharToDigit(z, 10)>=0 )
+        {
+            ss += z;
+            z = static_cast<char_type>(s.get());
+        }
+
+        // we're leaving the last read character
+        // (it's not belonging to the value)
+        s.unget();
+
+        l.FromString(ss);
+
+    return s;
+    }
+
+public:
+
+
+    /*!
+        input from standard streams
+    */
+    friend std::istream & operator>>(std::istream & s, UInt<value_size> & l)
+    {
+        return InputFromStream<std::istream, std::string, char>(s, l);
+    }
+
+
+
+
+    /*
+        following methods are defined in:
+            ttmathuint_x86.h
+            ttmathuint_x86_64.h
+            ttmathuint_noasm.h
+    */
+
+#ifdef TTMATH_NOASM
+    static uint AddTwoWords(uint a, uint b, uint carry, uint * result);
+    static uint SubTwoWords(uint a, uint b, uint carry, uint * result);
+
+#ifdef TTMATH_PLATFORM64
+
+    union uint_
+    {
+        struct
+        {
+            unsigned int low;  // 32 bit
+            unsigned int high; // 32 bit
+        } u_;
+
+        uint u;                // 64 bit
+    };
+
+
+    static void DivTwoWords2(uint a,uint b, uint c, uint * r, uint * rest);
+    static uint DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_);
+    static uint DivTwoWordsUnnormalize(uint u, uint d);
+    static unsigned int DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_);
+    static void MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_);
+
+#endif // TTMATH_PLATFORM64
+#endif // TTMATH_NOASM
+
+
+private:
+    uint Rcl2_one(uint c);
+    uint Rcr2_one(uint c);
+    uint Rcl2(uint bits, uint c);
+    uint Rcr2(uint bits, uint c);
+
+public:
+    static const char * LibTypeStr();
+    static LibTypeCode LibType();
+    uint Add(const UInt<value_size> & ss2, uint c=0);
+    uint AddInt(uint value, uint index = 0);
+    uint AddTwoInts(uint x2, uint x1, uint index);
+    static uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
+    uint Sub(const UInt<value_size> & ss2, uint c=0);
+    uint SubInt(uint value, uint index = 0);
+    static uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
+    static sint FindLeadingBitInWord(uint x);
+    static sint FindLowestBitInWord(uint x);
+    static uint SetBitInWord(uint & value, uint bit);
+    static void MulTwoWords(uint a, uint b, uint * result_high, uint * result_low);
+    static void DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest);
+
+};
+
+
+
+/*!
+    this specialization is needed in order to not confused the compiler "error: ISO C++ forbids zero-size array"
+    when compiling Mul3Big2() method
+*/
+template<>
+class UInt<0>
+{
+public:
+    uint table[1];
+
+    void Mul2Big(const UInt<0> &, UInt<0> &) { TTMATH_ASSERT(false) };
+    void SetZero() { TTMATH_ASSERT(false) };
+    uint AddTwoInts(uint, uint, uint) { TTMATH_ASSERT(false) return 0; };
+};
+
+
+} //namespace
+
+
+#include "ttmathuint_x86.h"
+#include "ttmathuint_x86_64.h"
+#include "ttmathuint_noasm.h"
+
+#endif
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_noasm.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,1013 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef headerfilettmathuint_noasm
+#define headerfilettmathuint_noasm
+
+
+#ifdef TTMATH_NOASM
+
+/*!
+	\file ttmathuint_noasm.h
+    \brief template class UInt<uint> with methods without any assembler code
+
+	this file is included at the end of ttmathuint.h
+*/
+
+
+namespace ttmath
+{
+
+	/*!
+		returning the string represents the currect type of the library
+		we have following types:
+		  asm_vc_32   - with asm code designed for Microsoft Visual C++ (32 bits)
+		  asm_gcc_32  - with asm code designed for GCC (32 bits)
+		  asm_vc_64   - with asm for VC (64 bit)
+		  asm_gcc_64  - with asm for GCC (64 bit)
+		  no_asm_32   - pure C++ version (32 bit) - without any asm code
+		  no_asm_64   - pure C++ version (64 bit) - without any asm code
+	*/
+	template<uint value_size>
+	const char * UInt<value_size>::LibTypeStr()
+	{
+		#ifdef TTMATH_PLATFORM32
+			static const char info[] = "no_asm_32";
+		#endif		
+
+		#ifdef TTMATH_PLATFORM64
+			static const char info[] = "no_asm_64";
+		#endif
+
+	return info;
+	}
+
+	
+	/*!
+		returning the currect type of the library
+	*/
+	template<uint value_size>
+	LibTypeCode UInt<value_size>::LibType()
+	{
+		#ifdef TTMATH_PLATFORM32
+			LibTypeCode info = no_asm_32;
+		#endif		
+
+		#ifdef TTMATH_PLATFORM64
+			LibTypeCode info = no_asm_64;
+		#endif
+
+	return info;
+	}
+
+
+	/*!
+		this method adds two words together
+		returns carry
+
+		this method is created only when TTMATH_NOASM macro is defined
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddTwoWords(uint a, uint b, uint carry, uint * result)
+	{
+	uint temp;
+
+		if( carry == 0 )
+		{
+			temp = a + b;
+
+			if( temp < a )
+				carry = 1;
+		}
+		else
+		{
+			carry = 1;
+			temp  = a + b + carry;
+
+			if( temp > a ) // !(temp<=a)
+				carry = 0;
+		}
+
+		*result = temp;
+
+	return carry;
+	}
+
+
+
+	/*!
+		this method adding ss2 to the this and adding carry if it's defined
+		(this = this + ss2 + c)
+
+		c must be zero or one (might be a bigger value than 1)
+		function returns carry (1) (if it was)
+	*/
+	
+	template<uint value_size>
+	uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
+	{
+	uint i;
+
+		for(i=0 ; i<value_size ; ++i)
+			c = AddTwoWords(table[i], ss2.table[i], c, &table[i]);
+
+		TTMATH_LOGC("UInt::Add", c)
+	
+	return c;
+	}
+
+
+	/*!
+		this method adds one word (at a specific position)
+		and returns a carry (if it was)
+
+		if we've got (value_size=3):
+			table[0] = 10;
+			table[1] = 30;
+			table[2] = 5;	
+		and we call:
+			AddInt(2,1)
+		then it'll be:
+			table[0] = 10;
+			table[1] = 30 + 2;
+			table[2] = 5;
+
+		of course if there was a carry from table[2] it would be returned
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddInt(uint value, uint index)
+	{
+	uint i, c;
+
+		TTMATH_ASSERT( index < value_size )
+
+
+		c = AddTwoWords(table[index], value, 0, &table[index]);
+
+		for(i=index+1 ; i<value_size && c ; ++i)
+			c = AddTwoWords(table[i], 0, c, &table[i]);
+
+		TTMATH_LOGC("UInt::AddInt", c)
+	
+	return c;
+	}
+
+
+
+
+
+	/*!
+		this method adds only two unsigned words to the existing value
+		and these words begin on the 'index' position
+		(it's used in the multiplication algorithm 2)
+
+		index should be equal or smaller than value_size-2 (index <= value_size-2)
+		x1 - lower word, x2 - higher word
+
+		for example if we've got value_size equal 4 and:
+			table[0] = 3
+			table[1] = 4
+			table[2] = 5
+			table[3] = 6
+		then let
+			x1 = 10
+			x2 = 20
+		and
+			index = 1
+
+		the result of this method will be:
+			table[0] = 3
+			table[1] = 4 + x1 = 14
+			table[2] = 5 + x2 = 25
+			table[3] = 6
+		
+		and no carry at the end of table[3]
+
+		(of course if there was a carry in table[2](5+20) then 
+		this carry would be passed to the table[3] etc.)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
+	{
+	uint i, c;
+
+		TTMATH_ASSERT( index < value_size - 1 )
+
+
+		c = AddTwoWords(table[index],   x1, 0, &table[index]);
+		c = AddTwoWords(table[index+1], x2, c, &table[index+1]);
+
+		for(i=index+2 ; i<value_size && c ; ++i)
+			c = AddTwoWords(table[i], 0, c, &table[i]);
+
+		TTMATH_LOGC("UInt::AddTwoInts", c)
+	
+	return c;
+	}
+
+
+
+	/*!
+		this static method addes one vector to the other
+		'ss1' is larger in size or equal to 'ss2'
+
+		ss1 points to the first (larger) vector
+		ss2 points to the second vector
+		ss1_size - size of the ss1 (and size of the result too)
+		ss2_size - size of the ss2
+		result - is the result vector (which has size the same as ss1: ss1_size)
+
+		Example:  ss1_size is 5, ss2_size is 3
+		ss1:      ss2:   result (output):
+		  5        1         5+1
+		  4        3         4+3
+		  2        7         2+7
+		  6                  6
+		  9                  9
+	  of course the carry is propagated and will be returned from the last item
+	  (this method is used by the Karatsuba multiplication algorithm)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+	{
+	uint i, c = 0;
+
+		TTMATH_ASSERT( ss1_size >= ss2_size )
+		
+		for(i=0 ; i<ss2_size ; ++i)
+			c = AddTwoWords(ss1[i], ss2[i], c, &result[i]);
+
+		for( ; i<ss1_size ; ++i)
+			c = AddTwoWords(ss1[i], 0, c, &result[i]);
+
+		TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
+
+	return c;
+	}
+
+
+
+
+	/*!
+		this method subtractes one word from the other
+		returns carry
+
+		this method is created only when TTMATH_NOASM macro is defined
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SubTwoWords(uint a, uint b, uint carry, uint * result)
+	{
+		if( carry == 0 )
+		{
+			*result = a - b;
+
+			if( a < b )
+				carry = 1;
+		}
+		else
+		{
+			carry   = 1;
+			*result = a - b - carry;
+
+			if( a > b ) // !(a <= b )
+				carry = 0;
+		}
+
+	return carry;
+	}
+
+
+
+
+	/*!
+		this method's subtracting ss2 from the 'this' and subtracting
+		carry if it has been defined
+		(this = this - ss2 - c)
+
+		c must be zero or one (might be a bigger value than 1)
+		function returns carry (1) (if it was)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
+	{
+	uint i;
+
+		for(i=0 ; i<value_size ; ++i)
+			c = SubTwoWords(table[i], ss2.table[i], c, &table[i]);
+
+		TTMATH_LOGC("UInt::Sub", c)
+
+	return c;
+	}
+
+
+
+
+	/*!
+		this method subtracts one word (at a specific position)
+		and returns a carry (if it was)
+
+		if we've got (value_size=3):
+			table[0] = 10;
+			table[1] = 30;
+			table[2] = 5;	
+		and we call:
+			SubInt(2,1)
+		then it'll be:
+			table[0] = 10;
+			table[1] = 30 - 2;
+			table[2] = 5;
+
+		of course if there was a carry from table[2] it would be returned
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SubInt(uint value, uint index)
+	{
+	uint i, c;
+
+		TTMATH_ASSERT( index < value_size )
+
+
+		c = SubTwoWords(table[index], value, 0, &table[index]);
+
+		for(i=index+1 ; i<value_size && c ; ++i)
+			c = SubTwoWords(table[i], 0, c, &table[i]);
+
+		TTMATH_LOGC("UInt::SubInt", c)
+	
+	return c;
+	}
+
+
+	/*!
+		this static method subtractes one vector from the other
+		'ss1' is larger in size or equal to 'ss2'
+
+		ss1 points to the first (larger) vector
+		ss2 points to the second vector
+		ss1_size - size of the ss1 (and size of the result too)
+		ss2_size - size of the ss2
+		result - is the result vector (which has size the same as ss1: ss1_size)
+
+		Example:  ss1_size is 5, ss2_size is 3
+		ss1:      ss2:   result (output):
+		  5        1         5-1
+		  4        3         4-3
+		  2        7         2-7
+		  6                  6-1  (the borrow from previous item)
+		  9                  9
+		                 return (carry): 0
+	  of course the carry (borrow) is propagated and will be returned from the last item
+	  (this method is used by the Karatsuba multiplication algorithm)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+	{
+	uint i, c = 0;
+
+		TTMATH_ASSERT( ss1_size >= ss2_size )
+		
+		for(i=0 ; i<ss2_size ; ++i)
+			c = SubTwoWords(ss1[i], ss2[i], c, &result[i]);
+
+		for( ; i<ss1_size ; ++i)
+			c = SubTwoWords(ss1[i], 0, c, &result[i]);
+
+		TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
+
+	return c;
+	}
+
+
+
+	/*!
+		this method moves all bits into the left hand side
+		return value <- this <- c
+
+		the lowest *bit* will be held the 'c' and
+		the state of one additional bit (on the left hand side)
+		will be returned
+
+		for example:
+		let this is 001010000
+		after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcl2_one(uint c)
+	{
+	uint i, new_c;
+
+		if( c != 0 )
+			c = 1;
+
+		for(i=0 ; i<value_size ; ++i)
+		{
+			new_c    = (table[i] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
+			table[i] = (table[i] << 1) | c;
+			c        = new_c;
+		}
+
+		TTMATH_LOGC("UInt::Rcl2_one", c)
+
+	return c;
+	}
+
+
+
+
+
+
+
+	/*!
+		this method moves all bits into the right hand side
+		c -> this -> return value
+
+		the highest *bit* will be held the 'c' and
+		the state of one additional bit (on the right hand side)
+		will be returned
+
+		for example:
+		let this is 000000010
+		after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcr2_one(uint c)
+	{
+	sint i; // signed i
+	uint new_c;
+
+		if( c != 0 )
+			c = TTMATH_UINT_HIGHEST_BIT;
+
+		for(i=sint(value_size)-1 ; i>=0 ; --i)
+		{
+			new_c    = (table[i] & 1) ? TTMATH_UINT_HIGHEST_BIT : 0;
+			table[i] = (table[i] >> 1) | c;
+			c        = new_c;
+		}
+
+		TTMATH_LOGC("UInt::Rcr2_one", c)
+
+	return c;
+	}
+
+
+
+
+	/*!
+		this method moves all bits into the left hand side
+		return value <- this <- c
+
+		the lowest *bits* will be held the 'c' and
+		the state of one additional bit (on the left hand side)
+		will be returned
+
+		for example:
+		let this is 001010000
+		after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcl2(uint bits, uint c)
+	{
+		TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+		uint move = TTMATH_BITS_PER_UINT - bits;
+		uint i, new_c;
+
+		if( c != 0 )
+			c = TTMATH_UINT_MAX_VALUE >> move;
+
+		for(i=0 ; i<value_size ; ++i)
+		{
+			new_c    = table[i] >> move;
+			table[i] = (table[i] << bits) | c;
+			c        = new_c;
+		}
+
+		TTMATH_LOGC("UInt::Rcl2", c)
+
+	return (c & 1);
+	}
+
+
+
+
+	/*!
+		this method moves all bits into the right hand side
+		C -> this -> return value
+
+		the highest *bits* will be held the 'c' and
+		the state of one additional bit (on the right hand side)
+		will be returned
+
+		for example:
+		let this is 000000010
+		after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcr2(uint bits, uint c)
+	{
+		TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+		uint move = TTMATH_BITS_PER_UINT - bits;
+		sint i; // signed
+		uint new_c;
+
+		if( c != 0 )
+			c = TTMATH_UINT_MAX_VALUE << move;
+
+		for(i=value_size-1 ; i>=0 ; --i)
+		{
+			new_c    = table[i] << move;
+			table[i] = (table[i] >> bits) | c;
+			c        = new_c;
+		}
+
+		TTMATH_LOGC("UInt::Rcr2", c)
+
+	return (c & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
+	}
+
+
+
+
+	/*!
+		this method returns the number of the highest set bit in x
+		if the 'x' is zero this method returns '-1'
+	*/
+	template<uint value_size>
+	sint UInt<value_size>::FindLeadingBitInWord(uint x)
+	{
+		if( x == 0 )
+			return -1;
+
+		uint bit = TTMATH_BITS_PER_UINT - 1;
+		
+		while( (x & TTMATH_UINT_HIGHEST_BIT) == 0 )
+		{
+			x = x << 1;
+			--bit;
+		}
+
+	return bit;
+	}
+
+
+
+	/*!
+		this method returns the number of the highest set bit in x
+		if the 'x' is zero this method returns '-1'
+	*/
+	template<uint value_size>
+	sint UInt<value_size>::FindLowestBitInWord(uint x)
+	{
+		if( x == 0 )
+			return -1;
+
+		uint bit = 0;
+		
+		while( (x & 1) == 0 )
+		{
+			x = x >> 1;
+			++bit;
+		}
+
+	return bit;
+	}
+
+
+
+	/*!
+		this method sets a special bit in the 'value'
+		and returns the last state of the bit (zero or one)
+
+		bit is from <0,TTMATH_BITS_PER_UINT-1>
+
+		e.g.
+		 uint x = 100;
+		 uint bit = SetBitInWord(x, 3);
+		 now: x = 108 and bit = 0
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
+	{
+		TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
+
+		uint mask = 1;
+
+		if( bit > 0 )
+			mask = mask << bit;
+
+		uint last = value & mask;
+		value     = value | mask;
+
+	return (last != 0) ? 1 : 0;
+	}
+
+
+
+
+
+
+	/*!
+	 *
+	 * Multiplication
+	 *
+	 *
+	*/
+
+
+	/*!
+		multiplication: result_high:result_low = a * b
+		result_high - higher word of the result
+		result_low  - lower word of the result
+	
+		this methos never returns a carry
+		this method is used in the second version of the multiplication algorithms
+	*/
+	template<uint value_size>
+	void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low)
+	{
+	#ifdef TTMATH_PLATFORM32
+
+		/*
+			on 32bit platforms we have defined 'unsigned long long int' type known as 'ulint' in ttmath namespace
+			this type has 64 bits, then we're using only one multiplication: 32bit * 32bit = 64bit
+		*/
+
+		union uint_
+		{
+			struct
+			{
+				uint low;  // 32 bits
+				uint high; // 32 bits
+			} u_;
+
+			ulint u;       // 64 bits
+		} res;
+
+		res.u = ulint(a) * ulint(b);     // multiply two 32bit words, the result has 64 bits
+
+		*result_high = res.u_.high;
+		*result_low  = res.u_.low;
+
+	#else
+
+		/*
+			64 bits platforms
+
+			we don't have a native type which has 128 bits
+			then we're splitting 'a' and 'b' to 4 parts (high and low halves)
+			and using 4 multiplications (with additions and carry correctness)
+		*/
+
+		uint_ a_;
+		uint_ b_;
+		uint_ res_high1, res_high2;
+		uint_ res_low1,  res_low2;
+		
+		a_.u = a;
+		b_.u = b;
+
+		/*
+			the multiplication is as follows (schoolbook algorithm with O(n^2) ):
+
+                                                   32 bits         32 bits
+
+                                             +--------------------------------+
+                                             |   a_.u_.high   |   a_.u_.low   |
+                                             +--------------------------------+
+                                             |   b_.u_.high   |   b_.u_.low   |
+            +--------------------------------+--------------------------------+
+            |           res_high1.u          |           res_low1.u           |
+            +--------------------------------+--------------------------------+
+            |           res_high2.u          |           res_low2.u           |
+            +--------------------------------+--------------------------------+
+
+                          64 bits                          64 bits
+		*/
+
+
+		uint_ temp;
+
+		res_low1.u        = uint(b_.u_.low) * uint(a_.u_.low);
+
+		temp.u            = uint(res_low1.u_.high) + uint(b_.u_.low) * uint(a_.u_.high);
+		res_low1.u_.high  = temp.u_.low;
+		res_high1.u_.low  = temp.u_.high;
+		res_high1.u_.high = 0;
+
+		res_low2.u_.low   = 0;
+		temp.u            = uint(b_.u_.high) * uint(a_.u_.low);
+		res_low2.u_.high  = temp.u_.low;
+
+		res_high2.u       = uint(b_.u_.high) * uint(a_.u_.high) + uint(temp.u_.high);
+
+		uint c = AddTwoWords(res_low1.u, res_low2.u, 0, &res_low2.u);
+		AddTwoWords(res_high1.u, res_high2.u, c, &res_high2.u);                 // there is no carry from here
+
+		*result_high = res_high2.u;
+		*result_low  = res_low2.u;
+
+	#endif
+	}
+
+
+
+
+	/*!
+	 *
+	 * Division
+	 *
+	 *
+	*/
+	
+
+	/*!
+		this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
+		r = a:b / c and rest - remainder
+		
+		*
+		* WARNING:
+		* the c has to be suitably large for the result being keeped in one word,
+		* if c is equal zero there'll be a hardware interruption (0)
+		* and probably the end of your program
+		*
+	*/
+	template<uint value_size>
+	void UInt<value_size>::DivTwoWords(uint a, uint b, uint c, uint * r, uint * rest)
+	{
+	// (a < c ) for the result to be one word
+	TTMATH_ASSERT( c != 0 && a < c )
+
+	#ifdef TTMATH_PLATFORM32
+
+		union
+		{
+			struct
+			{
+				uint low;  // 32 bits
+				uint high; // 32 bits
+			} u_;
+
+			ulint u;       // 64 bits
+		} ab;
+
+		ab.u_.high = a;
+		ab.u_.low  = b;
+
+		*r    = uint(ab.u / c);
+		*rest = uint(ab.u % c);
+
+	#else
+
+		uint_ c_;
+		c_.u = c;
+
+
+		if( a == 0 )
+		{
+			*r    = b / c;
+			*rest = b % c;
+		}
+		else
+		if( c_.u_.high == 0 )
+		{
+			// higher half of 'c' is zero
+			// then higher half of 'a' is zero too (look at the asserts at the beginning - 'a' is smaller than 'c')
+			uint_ a_, b_, res_, temp1, temp2;
+
+			a_.u = a;
+			b_.u = b;
+
+			temp1.u_.high = a_.u_.low;
+			temp1.u_.low  = b_.u_.high;
+
+			res_.u_.high  = (unsigned int)(temp1.u / c);
+			temp2.u_.high = (unsigned int)(temp1.u % c);
+			temp2.u_.low  = b_.u_.low;
+			
+			res_.u_.low  = (unsigned int)(temp2.u / c);
+			*rest        = temp2.u % c;
+
+			*r = res_.u;
+		}
+		else
+		{
+			return DivTwoWords2(a, b, c,  r,  rest);
+		}
+
+	#endif
+	}
+
+
+#ifdef TTMATH_PLATFORM64
+
+
+	/*!
+		this method is available only on 64bit platforms
+		
+		the same algorithm like the third division algorithm in ttmathuint.h
+		but now with the radix=2^32
+	*/
+	template<uint value_size>
+	void UInt<value_size>::DivTwoWords2(uint a, uint b, uint c, uint * r, uint * rest)
+	{
+		// a is not zero
+		// c_.u_.high is not zero
+
+		uint_ a_, b_, c_, u_, q_;
+		unsigned int u3; // 32 bit
+
+		a_.u  = a;
+		b_.u  = b;
+		c_.u  = c;
+
+		// normalizing
+		uint d = DivTwoWordsNormalize(a_, b_, c_);
+
+		// loop from j=1 to j=0
+		//   the first step (for j=2) is skipped because our result is only in one word,
+		//   (first 'q' were 0 and nothing would be changed)
+		u_.u_.high = a_.u_.high;
+		u_.u_.low  = a_.u_.low;
+		u3         = b_.u_.high;
+		q_.u_.high = DivTwoWordsCalculate(u_, u3, c_);
+		MultiplySubtract(u_, u3, q_.u_.high, c_);
+		
+		u_.u_.high = u_.u_.low;
+		u_.u_.low  = u3;
+		u3         = b_.u_.low;
+		q_.u_.low  = DivTwoWordsCalculate(u_, u3, c_);
+		MultiplySubtract(u_, u3, q_.u_.low, c_);
+
+		*r = q_.u;
+
+		// unnormalizing for the remainder
+		u_.u_.high = u_.u_.low;
+		u_.u_.low  = u3;
+		*rest = DivTwoWordsUnnormalize(u_.u, d);
+	}
+
+
+
+	
+	template<uint value_size>
+	uint UInt<value_size>::DivTwoWordsNormalize(uint_ & a_, uint_ & b_, uint_ & c_)
+	{
+		uint d = 0;
+
+		for( ; (c_.u & TTMATH_UINT_HIGHEST_BIT) == 0 ; ++d )
+		{
+			c_.u = c_.u << 1;
+			
+			uint bc = b_.u & TTMATH_UINT_HIGHEST_BIT; // carry from 'b'
+
+			b_.u = b_.u << 1;
+			a_.u = a_.u << 1; // carry bits from 'a' are simply skipped 
+
+			if( bc )
+				a_.u = a_.u | 1;
+		}
+
+	return d;
+	}
+
+
+	template<uint value_size>
+	uint UInt<value_size>::DivTwoWordsUnnormalize(uint u, uint d)
+	{
+		if( d == 0 )
+			return u;
+
+		u = u >> d;
+
+	return u;
+	}
+
+
+	template<uint value_size>
+	unsigned int UInt<value_size>::DivTwoWordsCalculate(uint_ u_, unsigned int u3, uint_ v_)
+	{
+	bool next_test;
+	uint_ qp_, rp_, temp_;
+
+		qp_.u = u_.u / uint(v_.u_.high);
+		rp_.u = u_.u % uint(v_.u_.high);
+
+		TTMATH_ASSERT( qp_.u_.high==0 || qp_.u_.high==1 )
+
+		do
+		{
+			bool decrease = false;
+
+			if( qp_.u_.high == 1 )
+				decrease = true;
+			else
+			{
+				temp_.u_.high = rp_.u_.low;
+				temp_.u_.low  = u3;
+
+				if( qp_.u * uint(v_.u_.low) > temp_.u )
+					decrease = true;
+			}
+			
+			next_test = false;
+
+			if( decrease )
+			{
+				--qp_.u;
+				rp_.u += v_.u_.high;
+
+				if( rp_.u_.high == 0 ) 
+					next_test = true;
+			}
+		}
+		while( next_test );
+
+	return qp_.u_.low;
+	}
+
+
+	template<uint value_size>
+	void UInt<value_size>::MultiplySubtract(uint_ & u_, unsigned int & u3, unsigned int & q, uint_ v_)
+	{
+	uint_ temp_;
+		
+		uint res_high;
+		uint res_low;
+
+		MulTwoWords(v_.u, q, &res_high, &res_low);
+
+		uint_ sub_res_high_;
+		uint_ sub_res_low_;
+
+		temp_.u_.high = u_.u_.low;
+		temp_.u_.low  = u3;
+
+		uint c = SubTwoWords(temp_.u, res_low, 0, &sub_res_low_.u);
+			
+		temp_.u_.high = 0;
+		temp_.u_.low  = u_.u_.high;
+		c = SubTwoWords(temp_.u, res_high, c, &sub_res_high_.u);
+
+		if( c )
+		{
+			--q;
+
+			c = AddTwoWords(sub_res_low_.u, v_.u, 0, &sub_res_low_.u);
+			AddTwoWords(sub_res_high_.u, 0, c, &sub_res_high_.u);
+		}
+
+		u_.u_.high = sub_res_high_.u_.low;
+		u_.u_.low  = sub_res_low_.u_.high;
+		u3         = sub_res_low_.u_.low;
+	}
+
+#endif // #ifdef TTMATH_PLATFORM64
+
+
+
+} //namespace
+
+
+#endif //ifdef TTMATH_NOASM
+#endif
+
+
+
+
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,1602 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+#ifndef headerfilettmathuint_x86
+#define headerfilettmathuint_x86
+
+
+#ifndef TTMATH_NOASM
+#ifdef TTMATH_PLATFORM32
+
+
+/*!
+	\file ttmathuint_x86.h
+    \brief template class UInt<uint> with assembler code for 32bit x86 processors
+
+	this file is included at the end of ttmathuint.h
+*/
+
+
+
+/*!
+    \brief a namespace for the TTMath library
+*/
+namespace ttmath
+{
+
+	/*!
+		returning the string represents the currect type of the library
+		we have following types:
+		  asm_vc_32   - with asm code designed for Microsoft Visual C++ (32 bits)
+		  asm_gcc_32  - with asm code designed for GCC (32 bits)
+		  asm_vc_64   - with asm for VC (64 bit)
+		  asm_gcc_64  - with asm for GCC (64 bit)
+		  no_asm_32   - pure C++ version (32 bit) - without any asm code
+		  no_asm_64   - pure C++ version (64 bit) - without any asm code
+	*/
+	template<uint value_size>
+	const char * UInt<value_size>::LibTypeStr()
+	{
+		#ifndef __GNUC__
+			static const char info[] = "asm_vc_32";
+		#endif		
+
+		#ifdef __GNUC__
+			static const char info[] = "asm_gcc_32";
+		#endif
+
+	return info;
+	}
+
+
+	/*!
+		returning the currect type of the library
+	*/
+	template<uint value_size>
+	LibTypeCode UInt<value_size>::LibType()
+	{
+		#ifndef __GNUC__
+			LibTypeCode info = asm_vc_32;
+		#endif		
+
+		#ifdef __GNUC__
+			LibTypeCode info = asm_gcc_32;
+		#endif
+
+	return info;
+	}
+
+
+
+	/*!
+	*
+	*	basic mathematic functions
+	*
+	*/
+
+
+	/*!
+		adding ss2 to the this and adding carry if it's defined
+		(this = this + ss2 + c)
+
+		c must be zero or one (might be a bigger value than 1)
+		function returns carry (1) (if it has been)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	uint * p2 = const_cast<uint*>(ss2.table);
+
+		// we don't have to use TTMATH_REFERENCE_ASSERT here
+		// this algorithm doesn't require it
+
+		#ifndef __GNUC__
+			
+			//	this part might be compiled with for example visual c
+
+			__asm
+			{
+				push eax
+				push ebx
+				push ecx
+				push edx
+				push esi
+
+				mov ecx,[b]
+				
+				mov ebx,[p1]
+				mov esi,[p2]
+
+				xor edx,edx          // edx=0
+				mov eax,[c]
+				neg eax              // CF=1 if rax!=0 , CF=0 if rax==0
+
+			ttmath_loop:
+				mov eax,[esi+edx*4]
+				adc [ebx+edx*4],eax
+
+				inc edx
+				dec ecx
+			jnz ttmath_loop
+
+				adc ecx, ecx
+				mov [c], ecx
+
+				pop esi
+				pop edx
+				pop ecx
+				pop ebx
+				pop eax
+			}
+
+
+
+		#endif		
+			
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+			//	this part should be compiled with gcc
+			
+			__asm__ __volatile__(
+
+				"xorl %%edx, %%edx				\n"
+				"negl %%eax						\n"  // CF=1 if rax!=0 , CF=0 if rax==0
+
+			"1:									\n"
+				"movl (%%esi,%%edx,4), %%eax	\n"
+				"adcl %%eax, (%%ebx,%%edx,4)	\n"
+			
+				"incl %%edx						\n"
+				"decl %%ecx						\n"
+			"jnz 1b								\n"
+
+				"adc %%ecx, %%ecx				\n"
+
+				: "=c" (c), "=a" (dummy), "=d" (dummy2)
+				: "0" (b),  "1" (c), "b" (p1), "S" (p2)
+				: "cc", "memory" );
+		#endif
+
+		TTMATH_LOGC("UInt::Add", c)
+
+	return c;
+	}
+
+
+
+	/*!
+		adding one word (at a specific position)
+		and returning a carry (if it has been)
+
+		e.g.
+
+		if we've got (value_size=3):
+			table[0] = 10;
+			table[1] = 30;
+			table[2] = 5;	
+		and we call:
+			AddInt(2,1)
+		then it'll be:
+			table[0] = 10;
+			table[1] = 30 + 2;
+			table[2] = 5;
+
+		of course if there was a carry from table[2] it would be returned
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddInt(uint value, uint index)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	uint c;
+
+		TTMATH_ASSERT( index < value_size )
+
+		#ifndef __GNUC__
+
+			__asm
+			{
+				push eax
+				push ebx
+				push ecx
+				push edx
+
+				mov ecx, [b]
+				sub ecx, [index]				
+
+				mov edx, [index]
+				mov ebx, [p1]
+
+				mov eax, [value]
+
+			ttmath_loop:
+				add [ebx+edx*4], eax
+			jnc ttmath_end
+
+				mov eax, 1
+				inc edx
+				dec ecx
+			jnz ttmath_loop
+
+			ttmath_end:
+				setc al
+				movzx edx, al
+				mov [c], edx
+
+				pop edx
+				pop ecx
+				pop ebx
+				pop eax
+			}
+
+		#endif		
+			
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+			__asm__ __volatile__(
+			
+				"subl %%edx, %%ecx 				\n"
+
+			"1:									\n"
+				"addl %%eax, (%%ebx,%%edx,4)	\n"
+			"jnc 2f								\n"
+				
+				"movl $1, %%eax					\n"
+				"incl %%edx						\n"
+				"decl %%ecx						\n"
+			"jnz 1b								\n"
+
+			"2:									\n"
+				"setc %%al						\n"
+				"movzx %%al, %%edx				\n"
+
+				: "=d" (c),    "=a" (dummy), "=c" (dummy2)
+				: "0" (index), "1" (value),  "2" (b), "b" (p1)
+				: "cc", "memory" );
+
+		#endif
+	
+		TTMATH_LOGC("UInt::AddInt", c)
+
+	return c;
+	}
+
+
+
+
+	/*!
+		adding only two unsigned words to the existing value
+		and these words begin on the 'index' position
+		(it's used in the multiplication algorithm 2)
+
+		index should be equal or smaller than value_size-2 (index <= value_size-2)
+		x1 - lower word, x2 - higher word
+
+		for example if we've got value_size equal 4 and:
+			table[0] = 3
+			table[1] = 4
+			table[2] = 5
+			table[3] = 6
+		then let
+			x1 = 10
+			x2 = 20
+		and
+			index = 1
+
+		the result of this method will be:
+			table[0] = 3
+			table[1] = 4 + x1 = 14
+			table[2] = 5 + x2 = 25
+			table[3] = 6
+		
+		and no carry at the end of table[3]
+
+		(of course if there was a carry in table[2](5+20) then 
+		this carry would be passed to the table[3] etc.)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	uint c;
+
+		TTMATH_ASSERT( index < value_size - 1 )
+
+		#ifndef __GNUC__
+			__asm
+			{
+				push eax
+				push ebx
+				push ecx
+				push edx
+
+				mov ecx, [b]
+				sub ecx, [index]				
+
+				mov ebx, [p1]
+				mov edx, [index]
+
+				mov eax, [x1]
+				add [ebx+edx*4], eax
+				inc edx
+				dec ecx
+
+				mov eax, [x2]
+			
+			ttmath_loop:
+				adc [ebx+edx*4], eax
+			jnc ttmath_end
+
+				mov eax, 0
+				inc edx
+				dec ecx
+			jnz ttmath_loop
+
+			ttmath_end:
+				setc al
+				movzx edx, al
+				mov [c], edx
+				
+				pop edx
+				pop ecx
+				pop ebx
+				pop eax
+
+			}
+		#endif		
+			
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+			__asm__ __volatile__(
+			
+				"subl %%edx, %%ecx 				\n"
+				
+				"addl %%esi, (%%ebx,%%edx,4) 	\n"
+				"incl %%edx						\n"
+				"decl %%ecx						\n"
+
+			"1:									\n"
+				"adcl %%eax, (%%ebx,%%edx,4)	\n"
+			"jnc 2f								\n"
+
+				"mov $0, %%eax					\n"
+				"incl %%edx						\n"
+				"decl %%ecx						\n"
+			"jnz 1b								\n"
+
+			"2:									\n"
+				"setc %%al						\n"
+				"movzx %%al, %%eax				\n"
+
+				: "=a" (c), "=c" (dummy), "=d" (dummy2)
+				: "0" (x2), "1" (b),      "2" (index), "b" (p1), "S" (x1)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::AddTwoInts", c)
+	
+	return c;
+	}
+
+
+
+	/*!
+		this static method addes one vector to the other
+		'ss1' is larger in size or equal to 'ss2'
+
+		ss1 points to the first (larger) vector
+		ss2 points to the second vector
+		ss1_size - size of the ss1 (and size of the result too)
+		ss2_size - size of the ss2
+		result - is the result vector (which has size the same as ss1: ss1_size)
+
+		Example:  ss1_size is 5, ss2_size is 3
+		ss1:      ss2:   result (output):
+		  5        1         5+1
+		  4        3         4+3
+		  2        7         2+7
+		  6                  6
+		  9                  9
+	  of course the carry is propagated and will be returned from the last item
+	  (this method is used by the Karatsuba multiplication algorithm)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+	{
+		TTMATH_ASSERT( ss1_size >= ss2_size )
+
+		uint rest = ss1_size - ss2_size;
+		uint c;
+
+		#ifndef __GNUC__
+
+			//	this part might be compiled with for example visual c
+			__asm
+			{
+				pushad
+
+				mov ecx, [ss2_size]
+				xor edx, edx               // edx = 0, cf = 0
+
+				mov esi, [ss1]
+				mov ebx, [ss2]
+				mov edi, [result]
+
+			ttmath_loop:
+				mov eax, [esi+edx*4]
+				adc eax, [ebx+edx*4]
+				mov [edi+edx*4], eax
+
+				inc edx
+				dec ecx
+			jnz ttmath_loop
+
+				adc ecx, ecx             // ecx has the cf state
+
+				mov ebx, [rest]
+				or ebx, ebx
+				jz ttmath_end
+				
+				xor ebx, ebx             // ebx = 0
+				neg ecx                  // setting cf from ecx
+				mov ecx, [rest]          // ecx is != 0
+			
+			ttmath_loop2:
+				mov eax, [esi+edx*4]
+				adc eax, ebx 
+				mov [edi+edx*4], eax
+
+				inc edx
+				dec ecx
+			jnz ttmath_loop2
+
+				adc ecx, ecx
+
+			ttmath_end:
+				mov [c], ecx
+
+				popad
+			}
+
+		#endif		
+			
+
+		#ifdef __GNUC__
+			
+		//	this part should be compiled with gcc
+		uint dummy1, dummy2, dummy3;
+
+			__asm__ __volatile__(
+				"push %%edx							\n"
+				"xor %%edx, %%edx					\n"   // edx = 0, cf = 0
+			"1:										\n"
+				"mov (%%esi,%%edx,4), %%eax			\n"
+				"adc (%%ebx,%%edx,4), %%eax			\n"
+				"mov %%eax, (%%edi,%%edx,4)			\n"
+
+				"inc %%edx							\n"
+				"dec %%ecx							\n"
+			"jnz 1b									\n"
+
+				"adc %%ecx, %%ecx					\n"   // ecx has the cf state
+				"pop %%eax							\n"   // eax = rest
+
+				"or %%eax, %%eax					\n"
+				"jz 3f								\n"
+				
+				"xor %%ebx, %%ebx					\n"   // ebx = 0
+				"neg %%ecx							\n"   // setting cf from ecx
+				"mov %%eax, %%ecx					\n"   // ecx=rest and is != 0
+			"2:										\n"
+				"mov (%%esi, %%edx, 4), %%eax		\n"
+				"adc %%ebx, %%eax 					\n"
+				"mov %%eax, (%%edi, %%edx, 4)		\n"
+
+				"inc %%edx							\n"
+				"dec %%ecx							\n"
+			"jnz 2b									\n"
+
+				"adc %%ecx, %%ecx					\n"
+			"3:										\n"
+
+				: "=a" (dummy1), "=b" (dummy2), "=c" (c),       "=d" (dummy3)
+				:                "1" (ss2),     "2" (ss2_size), "3" (rest),   "S" (ss1),  "D" (result)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
+
+	return c;
+	}
+
+
+	/*!
+		subtracting ss2 from the 'this' and subtracting
+		carry if it has been defined
+		(this = this - ss2 - c)
+
+		c must be zero or one (might be a bigger value than 1)
+		function returns carry (1) (if it has been)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	uint * p2 = const_cast<uint*>(ss2.table);
+
+		// we don't have to use TTMATH_REFERENCE_ASSERT here
+		// this algorithm doesn't require it
+
+		#ifndef __GNUC__
+
+			__asm
+			{
+				push eax
+				push ebx
+				push ecx
+				push edx
+				push esi
+
+				mov ecx,[b]
+				
+				mov ebx,[p1]
+				mov esi,[p2]
+
+				xor edx,edx          // edx=0
+				mov eax,[c]
+				neg eax              // CF=1 if rax!=0 , CF=0 if rax==0
+
+			ttmath_loop:
+				mov eax,[esi+edx*4]
+				sbb [ebx+edx*4],eax
+
+				inc edx
+				dec ecx
+			jnz ttmath_loop
+
+				adc ecx, ecx
+				mov [c], ecx
+
+				pop esi
+				pop edx
+				pop ecx
+				pop ebx
+				pop eax
+			}
+
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+			__asm__  __volatile__(
+
+				"xorl %%edx, %%edx				\n"
+				"negl %%eax						\n"  // CF=1 if rax!=0 , CF=0 if rax==0
+
+			"1:									\n"
+				"movl (%%esi,%%edx,4), %%eax	\n"
+				"sbbl %%eax, (%%ebx,%%edx,4)	\n"
+			
+				"incl %%edx						\n"
+				"decl %%ecx						\n"
+			"jnz 1b								\n"
+
+				"adc %%ecx, %%ecx				\n"
+
+				: "=c" (c), "=a" (dummy), "=d" (dummy2)
+				: "0" (b),  "1" (c), "b" (p1), "S" (p2)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Sub", c)
+
+	return c;
+	}
+
+
+
+
+	/*!
+		this method subtracts one word (at a specific position)
+		and returns a carry (if it was)
+
+		e.g.
+
+		if we've got (value_size=3):
+			table[0] = 10;
+			table[1] = 30;
+			table[2] = 5;	
+		and we call:
+			SubInt(2,1)
+		then it'll be:
+			table[0] = 10;
+			table[1] = 30 - 2;
+			table[2] = 5;
+
+		of course if there was a carry from table[2] it would be returned
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SubInt(uint value, uint index)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	uint c;
+
+		TTMATH_ASSERT( index < value_size )
+
+		#ifndef __GNUC__
+
+			__asm
+			{
+				push eax
+				push ebx
+				push ecx
+				push edx
+
+				mov ecx, [b]
+				sub ecx, [index]				
+
+				mov edx, [index]
+				mov ebx, [p1]
+
+				mov eax, [value]
+
+			ttmath_loop:
+				sub [ebx+edx*4], eax
+			jnc ttmath_end
+
+				mov eax, 1
+				inc edx
+				dec ecx
+			jnz ttmath_loop
+
+			ttmath_end:
+				setc al
+				movzx edx, al
+				mov [c], edx
+
+				pop edx
+				pop ecx
+				pop ebx
+				pop eax
+			}
+
+		#endif		
+			
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+			__asm__ __volatile__(
+			
+				"subl %%edx, %%ecx 				\n"
+
+			"1:									\n"
+				"subl %%eax, (%%ebx,%%edx,4)	\n"
+			"jnc 2f								\n"
+				
+				"movl $1, %%eax					\n"
+				"incl %%edx						\n"
+				"decl %%ecx						\n"
+			"jnz 1b								\n"
+
+			"2:									\n"
+				"setc %%al						\n"
+				"movzx %%al, %%edx				\n"
+
+				: "=d" (c),    "=a" (dummy), "=c" (dummy2)
+				: "0" (index), "1" (value),  "2" (b), "b" (p1)
+				: "cc", "memory" );
+
+		#endif
+		
+		TTMATH_LOGC("UInt::SubInt", c)
+	
+	return c;
+	}
+
+
+
+	/*!
+		this static method subtractes one vector from the other
+		'ss1' is larger in size or equal to 'ss2'
+
+		ss1 points to the first (larger) vector
+		ss2 points to the second vector
+		ss1_size - size of the ss1 (and size of the result too)
+		ss2_size - size of the ss2
+		result - is the result vector (which has size the same as ss1: ss1_size)
+
+		Example:  ss1_size is 5, ss2_size is 3
+		ss1:      ss2:   result (output):
+		  5        1         5-1
+		  4        3         4-3
+		  2        7         2-7
+		  6                  6-1  (the borrow from previous item)
+		  9                  9
+		              return (carry): 0
+	  of course the carry (borrow) is propagated and will be returned from the last item
+	  (this method is used by the Karatsuba multiplication algorithm)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+	{
+		TTMATH_ASSERT( ss1_size >= ss2_size )
+
+		uint rest = ss1_size - ss2_size;
+		uint c;
+
+		#ifndef __GNUC__
+			
+			//	this part might be compiled with for example visual c
+
+			/*
+				the asm code is nearly the same as in AddVector
+				only two instructions 'adc' are changed to 'sbb'
+			*/
+			__asm
+			{
+				pushad
+
+				mov ecx, [ss2_size]
+				xor edx, edx               // edx = 0, cf = 0
+
+				mov esi, [ss1]
+				mov ebx, [ss2]
+				mov edi, [result]
+
+			ttmath_loop:
+				mov eax, [esi+edx*4]
+				sbb eax, [ebx+edx*4]
+				mov [edi+edx*4], eax
+
+				inc edx
+				dec ecx
+			jnz ttmath_loop
+
+				adc ecx, ecx             // ecx has the cf state
+
+				mov ebx, [rest]
+				or ebx, ebx
+				jz ttmath_end
+				
+				xor ebx, ebx             // ebx = 0
+				neg ecx                  // setting cf from ecx
+				mov ecx, [rest]          // ecx is != 0
+
+			ttmath_loop2:
+				mov eax, [esi+edx*4]
+				sbb eax, ebx 
+				mov [edi+edx*4], eax
+
+				inc edx
+				dec ecx
+			jnz ttmath_loop2
+
+				adc ecx, ecx
+
+			ttmath_end:
+				mov [c], ecx
+
+				popad
+			}
+
+		#endif		
+			
+
+		#ifdef __GNUC__
+			
+		//	this part should be compiled with gcc
+		uint dummy1, dummy2, dummy3;
+
+			__asm__ __volatile__(
+				"push %%edx							\n"
+				"xor %%edx, %%edx					\n"   // edx = 0, cf = 0
+			"1:										\n"
+				"mov (%%esi,%%edx,4), %%eax			\n"
+				"sbb (%%ebx,%%edx,4), %%eax			\n"
+				"mov %%eax, (%%edi,%%edx,4)			\n"
+
+				"inc %%edx							\n"
+				"dec %%ecx							\n"
+			"jnz 1b									\n"
+
+				"adc %%ecx, %%ecx					\n"   // ecx has the cf state
+				"pop %%eax							\n"   // eax = rest
+
+				"or %%eax, %%eax					\n"
+				"jz 3f								\n"
+				
+				"xor %%ebx, %%ebx					\n"   // ebx = 0
+				"neg %%ecx							\n"   // setting cf from ecx
+				"mov %%eax, %%ecx					\n"   // ecx=rest and is != 0
+			"2:										\n"
+				"mov (%%esi, %%edx, 4), %%eax		\n"
+				"sbb %%ebx, %%eax 					\n"
+				"mov %%eax, (%%edi, %%edx, 4)		\n"
+
+				"inc %%edx							\n"
+				"dec %%ecx							\n"
+			"jnz 2b									\n"
+
+				"adc %%ecx, %%ecx					\n"
+			"3:										\n"
+
+				: "=a" (dummy1), "=b" (dummy2), "=c" (c),       "=d" (dummy3)
+				:                "1" (ss2),     "2" (ss2_size), "3" (rest),   "S" (ss1),  "D" (result)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
+
+	return c;
+	}
+
+
+
+	/*!
+		this method moves all bits into the left hand side
+		return value <- this <- c
+
+		the lowest *bit* will be held the 'c' and
+		the state of one additional bit (on the left hand side)
+		will be returned
+
+		for example:
+		let this is 001010000
+		after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcl2_one(uint c)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+
+		#ifndef __GNUC__
+			__asm
+			{
+				push ebx
+				push ecx
+				push edx
+
+				mov ebx, [p1]
+				xor edx, edx
+				mov ecx, [c]
+				neg ecx
+				mov ecx, [b]
+
+			ttmath_loop:
+				rcl dword ptr [ebx+edx*4], 1
+				
+				inc edx
+				dec ecx
+			jnz ttmath_loop
+
+				adc ecx, ecx
+				mov [c], ecx
+				
+				pop edx
+				pop ecx
+				pop ebx
+			}
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+		__asm__  __volatile__(
+
+			"xorl %%edx, %%edx			\n"   // edx=0
+			"negl %%eax					\n"   // CF=1 if eax!=0 , CF=0 if eax==0
+
+		"1:								\n"
+			"rcll $1, (%%ebx, %%edx, 4)	\n"
+
+			"incl %%edx					\n"
+			"decl %%ecx					\n"
+		"jnz 1b							\n"
+
+			"adcl %%ecx, %%ecx			\n"
+
+			: "=c" (c), "=a" (dummy), "=d" (dummy2)
+			: "0" (b),  "1" (c), "b" (p1)
+			: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Rcl2_one", c)
+
+	return c;
+	}
+
+
+
+	/*!
+		this method moves all bits into the right hand side
+		c -> this -> return value
+
+		the highest *bit* will be held the 'c' and
+		the state of one additional bit (on the right hand side)
+		will be returned
+
+		for example:
+		let this is 000000010
+		after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcr2_one(uint c)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+
+		#ifndef __GNUC__
+			__asm
+			{
+				push ebx
+				push ecx
+
+				mov ebx, [p1]
+				mov ecx, [c]
+				neg ecx
+				mov ecx, [b]
+
+			ttmath_loop:
+				rcr dword ptr [ebx+ecx*4-4], 1
+				
+				dec ecx
+			jnz ttmath_loop
+
+				adc ecx, ecx
+				mov [c], ecx
+
+				pop ecx
+				pop ebx
+			}
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy;
+
+		__asm__  __volatile__(
+
+			"negl %%eax						\n"   // CF=1 if eax!=0 , CF=0 if eax==0
+
+		"1:									\n"
+			"rcrl $1, -4(%%ebx, %%ecx, 4)	\n"
+
+			"decl %%ecx						\n"
+		"jnz 1b								\n"
+
+			"adcl %%ecx, %%ecx				\n"
+
+			: "=c" (c), "=a" (dummy)
+			: "0" (b),  "1" (c), "b" (p1)
+			: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Rcr2_one", c)
+
+	return c;
+	}
+
+
+
+#ifdef _MSC_VER
+#pragma warning (disable : 4731)
+//warning C4731: frame pointer register 'ebp' modified by inline assembly code
+#endif
+	
+
+
+	/*!
+		this method moves all bits into the left hand side
+		return value <- this <- c
+
+		the lowest *bits* will be held the 'c' and
+		the state of one additional bit (on the left hand side)
+		will be returned
+
+		for example:
+		let this is 001010000
+		after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcl2(uint bits, uint c)
+	{
+	TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+		
+	uint b = value_size;
+	uint * p1 = table;
+
+		#ifndef __GNUC__
+			__asm
+			{
+				push eax
+				push ebx
+				push ecx
+				push edx
+				push esi
+				push edi
+				push ebp
+
+				mov edi, [b]
+
+				mov ecx, 32
+				sub ecx, [bits]
+				mov edx, -1
+				shr edx, cl
+
+				mov ecx, [bits]
+				mov ebx, [p1]
+				mov eax, [c]
+
+				mov ebp, edx         // ebp = mask (modified ebp - don't read/write to variables)
+
+				xor edx, edx         // edx = 0
+				mov esi, edx
+				or eax, eax
+				cmovnz esi, ebp      // if(c) esi=mask else esi=0
+
+			ttmath_loop:
+				rol dword ptr [ebx+edx*4], cl
+				
+				mov eax, [ebx+edx*4]
+				and eax, ebp
+				xor [ebx+edx*4], eax // clearing bits
+				or [ebx+edx*4], esi  // saving old value
+				mov esi, eax
+
+				inc edx
+				dec edi
+			jnz ttmath_loop
+
+				pop ebp              // restoring ebp
+
+				and eax, 1
+				mov [c], eax
+
+				pop edi
+				pop esi
+				pop edx
+				pop ecx
+				pop ebx
+				pop eax
+			}
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2, dummy3;
+
+		__asm__  __volatile__(
+
+			"push %%ebp						\n"
+			
+			"movl %%ecx, %%esi				\n"
+			"movl $32, %%ecx				\n"
+			"subl %%esi, %%ecx				\n"    // ecx = 32 - bits
+			"movl $-1, %%edx				\n"    // edx = -1 (all bits set to one)
+			"shrl %%cl, %%edx				\n"    // shifting (0 -> edx -> cf)  (cl times)
+			"movl %%edx, %%ebp				\n"    // ebp = edx = mask
+			"movl %%esi, %%ecx				\n"
+
+			"xorl %%edx, %%edx				\n"
+			"movl %%edx, %%esi				\n"
+			"orl %%eax, %%eax				\n"
+			"cmovnz %%ebp, %%esi			\n"    // if(c) esi=mask else esi=0
+
+		"1:									\n"
+			"roll %%cl, (%%ebx,%%edx,4)		\n"
+
+			"movl (%%ebx,%%edx,4), %%eax	\n"
+			"andl %%ebp, %%eax				\n"
+			"xorl %%eax, (%%ebx,%%edx,4)	\n"
+			"orl  %%esi, (%%ebx,%%edx,4)	\n"
+			"movl %%eax, %%esi				\n"
+			
+			"incl %%edx						\n"
+			"decl %%edi						\n"
+		"jnz 1b								\n"
+			
+			"and $1, %%eax					\n"
+
+			"pop %%ebp						\n"
+
+			: "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
+			: "0" (c),  "1" (b), "b" (p1), "c" (bits)
+			: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Rcl2", c)
+
+	return c;
+	}
+
+
+
+
+	/*!
+		this method moves all bits into the right hand side
+		C -> this -> return value
+
+		the highest *bits* will be held the 'c' and
+		the state of one additional bit (on the right hand side)
+		will be returned
+
+		for example:
+		let this is 000000010
+		after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcr2(uint bits, uint c)
+	{
+	TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+	uint b = value_size;
+	uint * p1 = table;
+
+		#ifndef __GNUC__
+			__asm
+			{
+				push eax
+				push ebx
+				push ecx
+				push edx
+				push esi
+				push edi
+				push ebp
+
+				mov edi, [b]
+
+				mov ecx, 32
+				sub ecx, [bits]
+				mov edx, -1
+				shl edx, cl
+
+				mov ecx, [bits]
+				mov ebx, [p1]
+				mov eax, [c]
+
+				mov ebp, edx         // ebp = mask (modified ebp - don't read/write to variables)
+
+				xor edx, edx         // edx = 0
+				mov esi, edx
+				add edx, edi
+				dec edx              // edx is pointing at the end of the table (on last word)
+				or eax, eax
+				cmovnz esi, ebp      // if(c) esi=mask else esi=0
+
+			ttmath_loop:
+				ror dword ptr [ebx+edx*4], cl
+				
+				mov eax, [ebx+edx*4]
+				and eax, ebp 
+				xor [ebx+edx*4], eax // clearing bits
+				or [ebx+edx*4], esi  // saving old value
+				mov esi, eax
+
+				dec edx
+				dec edi
+			jnz ttmath_loop
+
+				pop ebp              // restoring ebp
+
+				rol eax, 1           // 31bit will be first
+				and eax, 1  
+				mov [c], eax
+
+				pop edi
+				pop esi
+				pop edx
+				pop ecx
+				pop ebx
+				pop eax
+			}
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2, dummy3;
+
+			__asm__  __volatile__(
+
+			"push %%ebp						\n"
+			
+			"movl %%ecx, %%esi				\n"
+			"movl $32, %%ecx				\n"
+			"subl %%esi, %%ecx				\n"    // ecx = 32 - bits
+			"movl $-1, %%edx				\n"    // edx = -1 (all bits set to one)
+			"shll %%cl, %%edx				\n"    // shifting (cf <- edx <- 0)  (cl times)
+			"movl %%edx, %%ebp				\n"    // ebp = edx = mask
+			"movl %%esi, %%ecx				\n"
+
+			"xorl %%edx, %%edx				\n"
+			"movl %%edx, %%esi				\n"
+			"addl %%edi, %%edx				\n"
+			"decl %%edx						\n"    // edx is pointing at the end of the table (on last word)
+			"orl %%eax, %%eax				\n"
+			"cmovnz %%ebp, %%esi			\n"    // if(c) esi=mask else esi=0
+
+		"1:									\n"
+			"rorl %%cl, (%%ebx,%%edx,4)		\n"
+
+			"movl (%%ebx,%%edx,4), %%eax	\n"
+			"andl %%ebp, %%eax				\n"
+			"xorl %%eax, (%%ebx,%%edx,4)	\n"
+			"orl  %%esi, (%%ebx,%%edx,4)	\n"
+			"movl %%eax, %%esi				\n"
+			
+			"decl %%edx						\n"
+			"decl %%edi						\n"
+		"jnz 1b								\n"
+			
+			"roll $1, %%eax					\n"
+			"andl $1, %%eax					\n"
+
+			"pop %%ebp						\n"
+
+			: "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
+			: "0" (c),  "1" (b), "b" (p1), "c" (bits)
+			: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Rcr2", c)
+
+	return c;
+	}
+
+
+#ifdef _MSC_VER
+#pragma warning (default : 4731)
+#endif
+
+
+	/*
+		this method returns the number of the highest set bit in one 32-bit word
+		if the 'x' is zero this method returns '-1'
+	*/
+	template<uint value_size>
+	sint UInt<value_size>::FindLeadingBitInWord(uint x)
+	{
+	sint result;
+
+		#ifndef __GNUC__
+			__asm
+			{
+				push eax
+				push edx
+
+				mov edx,-1
+				bsr eax,[x]
+				cmovz eax,edx
+				mov [result], eax
+
+				pop edx
+				pop eax
+			}
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy;
+
+				__asm__ (
+
+				"movl $-1, %1          \n"
+				"bsrl %2, %0           \n"
+				"cmovz %1, %0          \n"
+
+				: "=r" (result), "=&r" (dummy)
+				: "r" (x)
+				: "cc" );
+
+		#endif
+
+	return result;
+	}
+
+
+
+	/*
+		this method returns the number of the smallest set bit in one 32-bit word
+		if the 'x' is zero this method returns '-1'
+	*/
+	template<uint value_size>
+	sint UInt<value_size>::FindLowestBitInWord(uint x)
+	{
+	sint result;
+
+		#ifndef __GNUC__
+			__asm
+			{
+				push eax
+				push edx
+
+				mov edx,-1
+				bsf eax,[x]
+				cmovz eax,edx
+				mov [result], eax
+
+				pop edx
+				pop eax
+			}
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy;
+
+				__asm__ (
+
+				"movl $-1, %1          \n"
+				"bsfl %2, %0           \n"
+				"cmovz %1, %0          \n"
+
+				: "=r" (result), "=&r" (dummy)
+				: "r" (x)
+				: "cc" );
+
+		#endif
+
+	return result;
+	}
+
+
+
+	/*!
+		this method sets a special bit in the 'value'
+		and returns the last state of the bit (zero or one)
+
+		bit is from <0,31>
+		e.g.
+		 uint x = 100;
+		 uint bit = SetBitInWord(x, 3);
+		 now: x = 108 and bit = 0
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
+	{
+		TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
+
+		uint old_bit;
+		uint v = value;
+
+		#ifndef __GNUC__
+			__asm
+			{
+			push ebx
+			push eax
+
+			mov eax, [v]
+			mov ebx, [bit]
+			bts eax, ebx
+			mov [v], eax
+
+			setc bl
+			movzx ebx, bl
+			mov [old_bit], ebx
+
+			pop eax
+			pop ebx
+			}
+		#endif
+
+
+		#ifdef __GNUC__
+			__asm__ (
+
+			"btsl %%ebx, %%eax		\n"
+			"setc %%bl				\n"
+			"movzx %%bl, %%ebx		\n"
+			
+			: "=a" (v), "=b" (old_bit)
+			: "0" (v),  "1" (bit)
+			: "cc" );
+
+		#endif
+
+		value = v;
+
+	return old_bit;
+	}
+
+
+
+
+	/*!
+		multiplication: result_high:result_low = a * b
+		result_high - higher word of the result
+		result_low  - lower word of the result
+	
+		this methos never returns a carry
+		this method is used in the second version of the multiplication algorithms
+	*/
+	template<uint value_size>
+	void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low)
+	{
+	/*
+		we must use these temporary variables in order to inform the compilator
+		that value pointed with result1 and result2 has changed
+
+		this has no effect in visual studio but it's useful when
+		using gcc and options like -Ox
+	*/
+	uint result1_;
+	uint result2_;
+
+		#ifndef __GNUC__
+
+			__asm
+			{
+			push eax
+			push edx
+
+			mov eax, [a]
+			mul dword ptr [b]
+
+			mov [result2_], edx
+			mov [result1_], eax
+
+			pop edx
+			pop eax
+			}
+
+		#endif
+
+
+		#ifdef __GNUC__
+
+		__asm__ (
+		
+			"mull %%edx			\n"
+
+			: "=a" (result1_), "=d" (result2_)
+			: "0" (a),         "1" (b)
+			: "cc" );
+
+		#endif
+
+
+		*result_low  = result1_;
+		*result_high = result2_;
+	}
+
+
+
+
+
+	/*!
+	 *
+	 * Division
+	 *
+	 *
+	*/
+	
+
+
+
+	/*!
+		this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
+		r = a:b / c and rest - remainder
+
+		*
+		* WARNING:
+		* if r (one word) is too small for the result or c is equal zero
+		* there'll be a hardware interruption (0)
+		* and probably the end of your program
+		*
+	*/
+	template<uint value_size>
+	void UInt<value_size>::DivTwoWords(uint a, uint b, uint c, uint * r, uint * rest)
+	{
+		uint r_;
+		uint rest_;
+		/*
+			these variables have similar meaning like those in
+			the multiplication algorithm MulTwoWords
+		*/
+
+		TTMATH_ASSERT( c != 0 )
+
+		#ifndef __GNUC__
+			__asm
+			{
+				push eax
+				push edx
+
+				mov edx, [a]
+				mov eax, [b]
+				div dword ptr [c]
+
+				mov [r_], eax
+				mov [rest_], edx
+
+				pop edx
+				pop eax
+			}
+		#endif
+
+
+		#ifdef __GNUC__
+		
+			__asm__ (
+
+			"divl %%ecx				\n"
+
+			: "=a" (r_), "=d" (rest_)
+			: "0" (b),   "1" (a), "c" (c)
+			: "cc" );
+
+		#endif
+
+
+		*r = r_;
+		*rest = rest_;
+
+	}
+
+
+
+} //namespace
+
+
+
+#endif //ifdef TTMATH_PLATFORM32
+#endif //ifndef TTMATH_NOASM
+#endif
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64.h	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,1222 @@
+/*
+ * This file is a part of TTMath Bignum Library
+ * and is distributed under the (new) BSD licence.
+ * Author: Tomasz Sowa <t.sowa_at_[hidden]>
+ */
+
+/* 
+ * Copyright (c) 2006-2009, Tomasz Sowa
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *    
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *    
+ *  * Neither the name Tomasz Sowa nor the names of contributors to this
+ *    project may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#ifndef headerfilettmathuint_x86_64
+#define headerfilettmathuint_x86_64
+
+
+#ifndef TTMATH_NOASM
+#ifdef TTMATH_PLATFORM64
+
+
+/*!
+	\file ttmathuint_x86_64.h
+    \brief template class UInt<uint> with assembler code for 64bit x86_64 processors
+
+	this file is included at the end of ttmathuint.h
+*/
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
+
+namespace ttmath
+{
+
+	#ifdef _MSC_VER
+
+		extern "C"
+			{
+			uint __fastcall ttmath_adc_x64(uint* p1, const uint* p2, uint nSize, uint c);
+			uint __fastcall ttmath_addindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
+			uint __fastcall ttmath_addindexed2_x64(uint* p1, uint nSize, uint nPos, uint nValue1, uint nValue2);
+			uint __fastcall ttmath_addvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
+			uint __fastcall ttmath_sbb_x64(uint* p1, const uint* p2, uint nSize, uint c);
+			uint __fastcall ttmath_subindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
+			uint __fastcall ttmath_subvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
+			uint __fastcall ttmath_rcl_x64(uint* p1, uint nSize, uint nLowestBit);
+			uint __fastcall ttmath_rcr_x64(uint* p1, uint nSize, uint nLowestBit);
+			uint __fastcall ttmath_div_x64(uint* pnValHi, uint* pnValLo, uint nDiv);
+			uint __fastcall ttmath_rcl2_x64(uint* p1, uint nSize, uint nBits, uint c);
+			uint __fastcall ttmath_rcr2_x64(uint* p1, uint nSize, uint nBits, uint c);
+			};
+	#endif
+
+
+	/*!
+		returning the string represents the currect type of the library
+		we have following types:
+		  asm_vc_32   - with asm code designed for Microsoft Visual C++ (32 bits)
+		  asm_gcc_32  - with asm code designed for GCC (32 bits)
+		  asm_vc_64   - with asm for VC (64 bit)
+		  asm_gcc_64  - with asm for GCC (64 bit)
+		  no_asm_32   - pure C++ version (32 bit) - without any asm code
+		  no_asm_64   - pure C++ version (64 bit) - without any asm code
+	*/
+	template<uint value_size>
+	const char * UInt<value_size>::LibTypeStr()
+	{
+		#ifdef _MSC_VER
+			static const char info[] = "asm_vc_64";
+		#endif		
+
+		#ifdef __GNUC__
+			static const char info[] = "asm_gcc_64";
+		#endif
+
+	return info;
+	}
+
+
+	/*!
+		returning the currect type of the library
+	*/
+	template<uint value_size>
+	LibTypeCode UInt<value_size>::LibType()
+	{
+		#ifdef _MSC_VER
+			LibTypeCode info = asm_vc_64;
+		#endif		
+
+		#ifdef __GNUC__
+			LibTypeCode info = asm_gcc_64;
+		#endif
+
+	return info;
+	}
+
+
+	/*!
+	*
+	*	basic mathematic functions
+	*
+	*/
+
+
+
+	/*!
+		this method adding ss2 to the this and adding carry if it's defined
+		(this = this + ss2 + c)
+
+		***this method is created only on a 64bit platform***
+
+		c must be zero or one (might be a bigger value than 1)
+		function returns carry (1) (if it was)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	const uint * p2 = ss2.table;
+
+		// we don't have to use TTMATH_REFERENCE_ASSERT here
+		// this algorithm doesn't require it
+
+		#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
+
+		#ifdef _MSC_VER
+			c = ttmath_adc_x64(p1,p2,b,c);
+		#endif
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+			/*
+				this part should be compiled with gcc
+			*/
+			__asm__ __volatile__(
+	
+				"xorq %%rdx, %%rdx				\n"
+				"negq %%rax						\n"     // CF=1 if rax!=0 , CF=0 if rax==0
+
+			"1:									\n"
+				"movq (%%rsi,%%rdx,8), %%rax	\n"
+				"adcq %%rax, (%%rbx,%%rdx,8)	\n"
+			
+				"incq %%rdx						\n"
+				"decq %%rcx						\n"
+			"jnz 1b								\n"
+
+				"adcq %%rcx, %%rcx				\n"
+
+				: "=c" (c), "=a" (dummy), "=d" (dummy2)
+				: "0" (b),  "1" (c), "b" (p1), "S" (p2)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Add", c)
+	
+	return c;
+	}
+
+
+
+	/*!
+		this method adds one word (at a specific position)
+		and returns a carry (if it was)
+
+		***this method is created only on a 64bit platform***
+
+
+		if we've got (value_size=3):
+			table[0] = 10;
+			table[1] = 30;
+			table[2] = 5;	
+		and we call:
+			AddInt(2,1)
+		then it'll be:
+			table[0] = 10;
+			table[1] = 30 + 2;
+			table[2] = 5;
+
+		of course if there was a carry from table[2] it would be returned
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddInt(uint value, uint index)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	uint c;
+
+		TTMATH_ASSERT( index < value_size )
+
+		#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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_addindexed_x64(p1,b,index,value);
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+	
+			__asm__ __volatile__(
+
+				"subq %%rdx, %%rcx 				\n"
+
+			"1:									\n"
+				"addq %%rax, (%%rbx,%%rdx,8)	\n"
+			"jnc 2f								\n"
+				
+				"movq $1, %%rax					\n"
+				"incq %%rdx						\n"
+				"decq %%rcx						\n"
+			"jnz 1b								\n"
+
+			"2:									\n"
+				"setc %%al						\n"
+				"movzx %%al, %%rdx				\n"
+
+				: "=d" (c),    "=a" (dummy), "=c" (dummy2)
+				: "0" (index), "1" (value),  "2" (b), "b" (p1)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::AddInt", c)
+	
+	return c;
+	}
+
+
+
+	/*!
+		this method adds only two unsigned words to the existing value
+		and these words begin on the 'index' position
+		(it's used in the multiplication algorithm 2)
+
+		***this method is created only on a 64bit platform***
+
+		index should be equal or smaller than value_size-2 (index <= value_size-2)
+		x1 - lower word, x2 - higher word
+
+		for example if we've got value_size equal 4 and:
+			table[0] = 3
+			table[1] = 4
+			table[2] = 5
+			table[3] = 6
+		then let
+			x1 = 10
+			x2 = 20
+		and
+			index = 1
+
+		the result of this method will be:
+			table[0] = 3
+			table[1] = 4 + x1 = 14
+			table[2] = 5 + x2 = 25
+			table[3] = 6
+		
+		and no carry at the end of table[3]
+
+		(of course if there was a carry in table[2](5+20) then 
+		this carry would be passed to the table[3] etc.)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	uint c;
+
+		TTMATH_ASSERT( index < value_size - 1 )
+
+		#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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+			__asm__ __volatile__(
+			
+				"subq %%rdx, %%rcx 				\n"
+				
+				"addq %%rsi, (%%rbx,%%rdx,8) 	\n"
+				"incq %%rdx						\n"
+				"decq %%rcx						\n"
+
+			"1:									\n"
+				"adcq %%rax, (%%rbx,%%rdx,8)	\n"
+			"jnc 2f								\n"
+
+				"mov $0, %%rax					\n"
+				"incq %%rdx						\n"
+				"decq %%rcx						\n"
+			"jnz 1b								\n"
+
+			"2:									\n"
+				"setc %%al						\n"
+				"movzx %%al, %%rax				\n"
+
+				: "=a" (c), "=c" (dummy), "=d" (dummy2)
+				: "0" (x2), "1" (b),      "2" (index), "b" (p1), "S" (x1)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::AddTwoInts", c)
+
+	return c;
+	}
+
+
+
+	/*!
+		this static method addes one vector to the other
+		'ss1' is larger in size or equal to 'ss2'
+
+		ss1 points to the first (larger) vector
+		ss2 points to the second vector
+		ss1_size - size of the ss1 (and size of the result too)
+		ss2_size - size of the ss2
+		result - is the result vector (which has size the same as ss1: ss1_size)
+
+		Example:  ss1_size is 5, ss2_size is 3
+		ss1:      ss2:   result (output):
+		  5        1         5+1
+		  4        3         4+3
+		  2        7         2+7
+		  6                  6
+		  9                  9
+	  of course the carry is propagated and will be returned from the last item
+	  (this method is used by the Karatsuba multiplication algorithm)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+	{
+		TTMATH_ASSERT( ss1_size >= ss2_size )
+
+		uint c;
+
+		#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
+
+
+		#ifdef _MSC_VER
+			 c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy1, dummy2, dummy3;	
+		uint rest = ss1_size - ss2_size;
+			
+			//	this part should be compiled with gcc
+		
+			__asm__ __volatile__(
+				"mov %%rdx, %%r8					\n"
+				"xor %%rdx, %%rdx					\n"   // rdx = 0, cf = 0
+			"1:										\n"
+				"mov (%%rsi,%%rdx,8), %%rax			\n"
+				"adc (%%rbx,%%rdx,8), %%rax			\n"
+				"mov %%rax, (%%rdi,%%rdx,8)			\n"
+
+				"inc %%rdx							\n"
+				"dec %%rcx							\n"
+			"jnz 1b									\n"
+
+				"adc %%rcx, %%rcx					\n"   // rcx has the cf state
+
+				"or %%r8, %%r8						\n"
+				"jz 3f								\n"
+				
+				"xor %%rbx, %%rbx					\n"   // ebx = 0
+				"neg %%rcx							\n"   // setting cf from rcx
+				"mov %%r8, %%rcx					\n"   // rcx=rest and is != 0
+			"2:										\n"
+				"mov (%%rsi, %%rdx, 8), %%rax		\n"
+				"adc %%rbx, %%rax 					\n"
+				"mov %%rax, (%%rdi, %%rdx, 8)		\n"
+
+				"inc %%rdx							\n"
+				"dec %%rcx							\n"
+			"jnz 2b									\n"
+
+				"adc %%rcx, %%rcx					\n"
+			"3:										\n"
+
+				: "=a" (dummy1), "=b" (dummy2), "=c" (c),       "=d" (dummy3)
+				:                "1" (ss2),     "2" (ss2_size), "3" (rest),   "S" (ss1),  "D" (result)
+				: "%r8", "cc", "memory" );
+
+		#endif
+
+		TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
+
+	return c;
+	}
+
+
+
+	/*!
+		this method's subtracting ss2 from the 'this' and subtracting
+		carry if it has been defined
+		(this = this - ss2 - c)
+
+		***this method is created only on a 64bit platform***
+
+		c must be zero or one (might be a bigger value than 1)
+		function returns carry (1) (if it was)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	const uint * p2 = ss2.table;
+	
+
+		// we don't have to use TTMATH_REFERENCE_ASSERT here
+		// this algorithm doesn't require it
+
+		#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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_sbb_x64(p1,p2,b,c);
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+			__asm__  __volatile__(
+	
+				"xorq %%rdx, %%rdx				\n"
+				"negq %%rax						\n"     // CF=1 if rax!=0 , CF=0 if rax==0
+
+			"1:									\n"
+				"movq (%%rsi,%%rdx,8), %%rax	\n"
+				"sbbq %%rax, (%%rbx,%%rdx,8)	\n"
+			
+				"incq %%rdx						\n"
+				"decq %%rcx						\n"
+			"jnz 1b								\n"
+
+				"adcq %%rcx, %%rcx				\n"
+
+				: "=c" (c), "=a" (dummy), "=d" (dummy2)
+				: "0" (b),  "1" (c), "b" (p1), "S" (p2)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Sub", c)
+
+	return c;
+	}
+
+
+
+	/*!
+		this method subtracts one word (at a specific position)
+		and returns a carry (if it was)
+
+		***this method is created only on a 64bit platform***
+
+		if we've got (value_size=3):
+			table[0] = 10;
+			table[1] = 30;
+			table[2] = 5;	
+		and we call:
+			SubInt(2,1)
+		then it'll be:
+			table[0] = 10;
+			table[1] = 30 - 2;
+			table[2] = 5;
+
+		of course if there was a carry from table[2] it would be returned
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SubInt(uint value, uint index)
+	{
+	uint b = value_size;
+	uint * p1 = table;
+	uint c;
+
+		TTMATH_ASSERT( index < value_size )
+
+		#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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_subindexed_x64(p1,b,index,value);
+		#endif
+
+
+		#ifdef __GNUC__
+			uint dummy, dummy2;
+
+			__asm__ __volatile__(
+			
+				"subq %%rdx, %%rcx 				\n"
+
+			"1:									\n"
+				"subq %%rax, (%%rbx,%%rdx,8)	\n"
+			"jnc 2f								\n"
+				
+				"movq $1, %%rax					\n"
+				"incq %%rdx						\n"
+				"decq %%rcx						\n"
+			"jnz 1b								\n"
+
+			"2:									\n"
+				"setc %%al						\n"
+				"movzx %%al, %%rdx				\n"
+
+				: "=d" (c),    "=a" (dummy), "=c" (dummy2)
+				: "0" (index), "1" (value),  "2" (b), "b" (p1)
+				: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::SubInt", c)
+
+	return c;
+	}
+
+
+	/*!
+		this static method subtractes one vector from the other
+		'ss1' is larger in size or equal to 'ss2'
+
+		ss1 points to the first (larger) vector
+		ss2 points to the second vector
+		ss1_size - size of the ss1 (and size of the result too)
+		ss2_size - size of the ss2
+		result - is the result vector (which has size the same as ss1: ss1_size)
+
+		Example:  ss1_size is 5, ss2_size is 3
+		ss1:      ss2:   result (output):
+		  5        1         5-1
+		  4        3         4-3
+		  2        7         2-7
+		  6                  6-1  (the borrow from previous item)
+		  9                  9
+		               return (carry): 0
+	  of course the carry (borrow) is propagated and will be returned from the last item
+	  (this method is used by the Karatsuba multiplication algorithm)
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
+	{
+		TTMATH_ASSERT( ss1_size >= ss2_size )
+
+		uint c;
+
+		#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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
+		#endif
+
+
+		#ifdef __GNUC__
+		
+		//	the asm code is nearly the same as in AddVector
+		//	only two instructions 'adc' are changed to 'sbb'
+		
+		uint dummy1, dummy2, dummy3;
+		uint rest = ss1_size - ss2_size;
+
+			__asm__ __volatile__(
+				"mov %%rdx, %%r8					\n"
+				"xor %%rdx, %%rdx					\n"   // rdx = 0, cf = 0
+			"1:										\n"
+				"mov (%%rsi,%%rdx,8), %%rax			\n"
+				"sbb (%%rbx,%%rdx,8), %%rax			\n"
+				"mov %%rax, (%%rdi,%%rdx,8)			\n"
+
+				"inc %%rdx							\n"
+				"dec %%rcx							\n"
+			"jnz 1b									\n"
+
+				"adc %%rcx, %%rcx					\n"   // rcx has the cf state
+
+				"or %%r8, %%r8						\n"
+				"jz 3f								\n"
+				
+				"xor %%rbx, %%rbx					\n"   // ebx = 0
+				"neg %%rcx							\n"   // setting cf from rcx
+				"mov %%r8, %%rcx					\n"   // rcx=rest and is != 0
+			"2:										\n"
+				"mov (%%rsi, %%rdx, 8), %%rax		\n"
+				"sbb %%rbx, %%rax 					\n"
+				"mov %%rax, (%%rdi, %%rdx, 8)		\n"
+
+				"inc %%rdx							\n"
+				"dec %%rcx							\n"
+			"jnz 2b									\n"
+
+				"adc %%rcx, %%rcx					\n"
+			"3:										\n"
+
+				: "=a" (dummy1), "=b" (dummy2), "=c" (c),       "=d" (dummy3)
+				:                "1" (ss2),     "2" (ss2_size), "3" (rest),   "S" (ss1),  "D" (result)
+				: "%r8", "cc", "memory" );
+
+		#endif
+
+		TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
+
+	return c;
+	}
+
+
+	/*!
+		this method moves all bits into the left hand side
+		return value <- this <- c
+
+		the lowest *bit* will be held the 'c' and
+		the state of one additional bit (on the left hand side)
+		will be returned
+
+		for example:
+		let this is 001010000
+		after Rcl2_one(1) there'll be 010100001 and Rcl2_one returns 0
+	
+		***this method is created only on a 64bit platform***
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcl2_one(uint c)
+	{
+	sint b = value_size;
+	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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_rcl_x64(p1,b,c);
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2;
+
+		__asm__  __volatile__(
+		
+			"xorq %%rdx, %%rdx			\n"   // rdx=0
+			"negq %%rax					\n"   // CF=1 if rax!=0 , CF=0 if rax==0
+
+		"1:								\n"
+			"rclq $1, (%%rbx, %%rdx, 8)	\n"
+
+			"incq %%rdx					\n"
+			"decq %%rcx					\n"
+		"jnz 1b							\n"
+
+			"adcq %%rcx, %%rcx			\n"
+
+			: "=c" (c), "=a" (dummy), "=d" (dummy2)
+			: "0" (b),  "1" (c), "b" (p1)
+			: "cc", "memory" );
+	
+		#endif
+
+		TTMATH_LOGC("UInt::Rcl2_one", c)
+
+	return c;
+	}
+
+
+	/*!
+		this method moves all bits into the right hand side
+		c -> this -> return value
+
+		the highest *bit* will be held the 'c' and
+		the state of one additional bit (on the right hand side)
+		will be returned
+
+		for example:
+		let this is 000000010
+		after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
+
+		***this method is created only on a 64bit platform***
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcr2_one(uint c)
+	{
+	sint b = value_size;
+	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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_rcr_x64(p1,b,c);
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy;
+
+		__asm__  __volatile__(
+
+			"negq %%rax						\n"   // CF=1 if rax!=0 , CF=0 if rax==0
+
+		"1:									\n"
+			"rcrq $1, -8(%%rbx, %%rcx, 8)	\n"
+
+			"decq %%rcx						\n"
+		"jnz 1b								\n"
+
+			"adcq %%rcx, %%rcx				\n"
+
+			: "=c" (c), "=a" (dummy)
+			: "0" (b),  "1" (c), "b" (p1)
+			: "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Rcr2_one", c)
+
+	return c;
+	}
+
+
+
+	/*!
+		this method moves all bits into the left hand side
+		return value <- this <- c
+
+		the lowest *bits* will be held the 'c' and
+		the state of one additional bit (on the left hand side)
+		will be returned
+
+		for example:
+		let this is 001010000
+		after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
+	
+		***this method is created only on a 64bit platform***
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcl2(uint bits, uint c)
+	{
+	TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+	uint b = value_size;
+	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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_rcl2_x64(p1,b,bits,c);
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy, dummy2, dummy3;
+
+		__asm__  __volatile__(
+		
+			"movq %%rcx, %%rsi				\n"
+			"movq $64, %%rcx				\n"
+			"subq %%rsi, %%rcx				\n"
+			"movq $-1, %%rdx				\n"
+			"shrq %%cl, %%rdx				\n"
+			"movq %%rdx, %%r8 				\n"
+			"movq %%rsi, %%rcx				\n"
+
+			"xorq %%rdx, %%rdx				\n"
+			"movq %%rdx, %%rsi				\n"
+			"orq %%rax, %%rax				\n"
+			"cmovnz %%r8, %%rsi				\n"
+
+		"1:									\n"
+			"rolq %%cl, (%%rbx,%%rdx,8)		\n"
+
+			"movq (%%rbx,%%rdx,8), %%rax	\n"
+			"andq %%r8, %%rax				\n"
+			"xorq %%rax, (%%rbx,%%rdx,8)	\n"
+			"orq  %%rsi, (%%rbx,%%rdx,8)	\n"
+			"movq %%rax, %%rsi				\n"
+			
+			"incq %%rdx						\n"
+			"decq %%rdi						\n"
+		"jnz 1b								\n"
+			
+			"and $1, %%rax					\n"
+
+			: "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
+			: "0" (c),  "1" (b), "b" (p1), "c" (bits)
+			: "%r8", "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Rcl2", c)
+
+	return c;
+	}
+
+
+	/*!
+		this method moves all bits into the right hand side
+		C -> this -> return value
+
+		the highest *bits* will be held the 'c' and
+		the state of one additional bit (on the right hand side)
+		will be returned
+
+		for example:
+		let this is 000000010
+		after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
+
+		***this method is created only on a 64bit platform***
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::Rcr2(uint bits, uint c)
+	{
+	TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
+
+	sint b = value_size;
+	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
+
+
+		#ifdef _MSC_VER
+			c = ttmath_rcr2_x64(p1,b,bits,c);
+		#endif
+
+
+		#ifdef __GNUC__
+			uint dummy, dummy2, dummy3;
+
+			__asm__  __volatile__(
+
+			"movq %%rcx, %%rsi				\n"
+			"movq $64, %%rcx				\n"
+			"subq %%rsi, %%rcx				\n"
+			"movq $-1, %%rdx				\n"
+			"shlq %%cl, %%rdx				\n"
+			"movq %%rdx, %%R8				\n"
+			"movq %%rsi, %%rcx				\n"
+
+			"xorq %%rdx, %%rdx				\n"
+			"movq %%rdx, %%rsi				\n"
+			"addq %%rdi, %%rdx				\n"
+			"decq %%rdx						\n"
+			"orq %%rax, %%rax				\n"
+			"cmovnz %%R8, %%rsi				\n"
+
+		"1:									\n"
+			"rorq %%cl, (%%rbx,%%rdx,8)		\n"
+
+			"movq (%%rbx,%%rdx,8), %%rax	\n"
+			"andq %%R8, %%rax				\n"
+			"xorq %%rax, (%%rbx,%%rdx,8)	\n"
+			"orq  %%rsi, (%%rbx,%%rdx,8)	\n"
+			"movq %%rax, %%rsi				\n"
+			
+			"decq %%rdx						\n"
+			"decq %%rdi						\n"
+		"jnz 1b								\n"
+			
+			"rolq $1, %%rax					\n"
+			"andq $1, %%rax					\n"
+
+			: "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
+			: "0" (c), "1" (b), "b" (p1), "c" (bits)
+			: "%r8", "cc", "memory" );
+
+		#endif
+
+		TTMATH_LOGC("UInt::Rcr2", c)
+
+	return c;
+	}
+
+
+	/*
+		this method returns the number of the highest set bit in one 64-bit word
+		if the 'x' is zero this method returns '-1'
+
+		***this method is created only on a 64bit platform***
+	*/
+	template<uint value_size>
+	sint UInt<value_size>::FindLeadingBitInWord(uint x)
+	{
+	sint result;
+
+
+		#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
+
+		
+		#ifdef _MSC_VER
+
+			unsigned long nIndex = 0;
+
+			if( _BitScanReverse64(&nIndex,x) == 0 )
+				result = -1;
+			else
+				result = nIndex;
+
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy;
+
+				__asm__ (
+
+				"movq $-1, %1          \n"
+				"bsrq %2, %0           \n"
+				"cmovz %1, %0          \n"
+
+				: "=r" (result), "=&r" (dummy)
+				: "r" (x)
+				: "cc" );
+
+		#endif
+
+
+	return result;
+	}
+
+
+	/*
+		this method returns the number of the highest set bit in one 64-bit word
+		if the 'x' is zero this method returns '-1'
+
+		***this method is created only on a 64bit platform***
+	*/
+	template<uint value_size>
+	sint UInt<value_size>::FindLowestBitInWord(uint x)
+	{
+	sint result;
+
+
+		#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
+
+		
+		#ifdef _MSC_VER
+
+			unsigned long nIndex = 0;
+
+			if( _BitScanForward64(&nIndex,x) == 0 )
+				result = -1;
+			else
+				result = nIndex;
+
+		#endif
+
+
+		#ifdef __GNUC__
+		uint dummy;
+
+				__asm__ (
+
+				"movq $-1, %1          \n"
+				"bsfq %2, %0           \n"
+				"cmovz %1, %0          \n"
+
+				: "=r" (result), "=&r" (dummy)
+				: "r" (x)
+				: "cc" );
+
+		#endif
+
+
+	return result;
+	}
+
+
+	/*!
+		this method sets a special bit in the 'value'
+		and returns the last state of the bit (zero or one)
+
+		***this method is created only on a 64bit platform***
+
+		bit is from <0,63>
+
+		e.g.
+		 uint x = 100;
+		 uint bit = SetBitInWord(x, 3);
+		 now: x = 108 and bit = 0
+	*/
+	template<uint value_size>
+	uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
+	{
+		TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
+		
+		uint old_bit;
+		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
+
+
+		#ifdef _MSC_VER
+			old_bit = _bittestandset64((__int64*)&value,bit) != 0;
+		#endif
+
+
+		#ifdef __GNUC__
+
+			__asm__ (
+
+			"btsq %%rbx, %%rax		\n"
+			"setc %%bl				\n"
+			"movzx %%bl, %%rbx		\n"
+			
+			: "=a" (v), "=b" (old_bit)
+			: "0" (v),  "1" (bit)
+			: "cc" );
+
+		#endif
+
+		value = v;
+
+	return old_bit;
+	}
+
+
+	/*!
+	 *
+	 * Multiplication
+	 *
+	 *
+	*/
+
+
+	/*!
+		multiplication: result_high:result_low = a * b
+		result_high - higher word of the result
+		result_low  - lower word of the result
+	
+		this methos never returns a carry
+		this method is used in the second version of the multiplication algorithms
+
+		***this method is created only on a 64bit platform***
+	*/
+	template<uint value_size>
+	void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low)
+	{
+	/*
+		we must use these temporary variables in order to inform the compilator
+		that value pointed with result1 and result2 has changed
+
+		this has no effect in visual studio but it's usefull when
+		using gcc and options like -O
+	*/
+	uint result1_;
+	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
+
+
+		#ifdef _MSC_VER
+			result1_ = _umul128(a,b,&result2_);
+		#endif
+
+
+		#ifdef __GNUC__
+
+		__asm__ (
+		
+			"mulq %%rdx			\n"
+
+			: "=a" (result1_), "=d" (result2_)
+			: "0" (a),         "1" (b)
+			: "cc" );
+
+		#endif
+
+
+		*result_low  = result1_;
+		*result_high = result2_;
+	}
+
+
+
+
+	/*!
+	 *
+	 * Division
+	 *
+	 *
+	*/
+	
+
+	/*!
+		this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
+		r = a:b / c and rest - remainder
+		
+		***this method is created only on a 64bit platform***
+
+		*
+		* WARNING:
+		* if r (one word) is too small for the result or c is equal zero
+		* there'll be a hardware interruption (0)
+		* and probably the end of your program
+		*
+	*/
+	template<uint value_size>
+	void UInt<value_size>::DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest)
+	{
+		uint r_;
+		uint rest_;
+		/*
+			these variables have similar meaning like those in
+			the multiplication algorithm MulTwoWords
+		*/
+
+		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
+
+
+		#ifdef _MSC_VER
+
+			ttmath_div_x64(&a,&b,c);
+			r_    = a;
+			rest_ = b;
+			
+		#endif
+
+
+		#ifdef __GNUC__
+		
+			__asm__ (
+
+			"divq %%rcx				\n"
+
+			: "=a" (r_), "=d" (rest_)
+			: "d" (a), "a" (b), "c" (c)
+			: "cc" );
+
+		#endif
+
+
+		*r = r_;
+		*rest = rest_;
+	}
+
+} //namespace
+
+
+#endif //ifdef TTMATH_PLATFORM64
+#endif //ifndef TTMATH_NOASM
+#endif
+
+
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath/ttmathuint_x86_64_msvc.asm	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,548 @@
+;
+; This file is a part of TTMath Bignum Library
+; and is distributed under the (new) BSD licence.
+; Author: Christian Kaiser <chk_at_[hidden]>
+;
+
+; 
+; Copyright (c) 2009, Christian Kaiser
+; All rights reserved.
+; 
+; Redistribution and use in source and binary forms, with or without
+; modification, are permitted provided that the following conditions are met:
+; 
+;  * Redistributions of source code must retain the above copyright notice,
+;    this list of conditions and the following disclaimer.
+;    
+;  * Redistributions in binary form must reproduce the above copyright
+;    notice, this list of conditions and the following disclaimer in the
+;    documentation and/or other materials provided with the distribution.
+;    
+;  * Neither the name Christian Kaiser nor the names of contributors to this
+;    project may be used to endorse or promote products derived
+;    from this software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+; THE POSSIBILITY OF SUCH DAMAGE.
+;
+
+;
+; compile with debug info:    ml64.exe /Zd /Zi ttmathuint_x86_64_msvc.asm
+; compile without debug info: ml64.exe ttmathuint_x86_64_msvc.asm
+; this create ttmathuint_x86_64_msvc.obj file which can be linked with your program
+;
+
+PUBLIC	ttmath_adc_x64
+PUBLIC	ttmath_addindexed_x64
+PUBLIC	ttmath_addindexed2_x64
+PUBLIC	ttmath_addvector_x64
+
+PUBLIC	ttmath_sbb_x64
+PUBLIC	ttmath_subindexed_x64
+PUBLIC	ttmath_subvector_x64
+
+PUBLIC	ttmath_rcl_x64
+PUBLIC	ttmath_rcr_x64
+
+PUBLIC	ttmath_rcl2_x64
+PUBLIC	ttmath_rcr2_x64
+
+PUBLIC	ttmath_div_x64
+
+;
+; Microsoft x86_64 convention: http://msdn.microsoft.com/en-us/library/9b372w95.aspx
+;
+;	"rax, rcx, rdx, r8-r11 are volatile."
+;	"rbx, rbp, rdi, rsi, r12-r15 are nonvolatile."
+;
+
+
+.CODE
+
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_adc_x64				PROC
+        ; rcx = p1
+        ; rdx = p2
+        ; r8 = nSize
+        ; r9 = nCarry
+
+        xor		rax, rax
+        xor		r11, r11
+        sub		rax, r9		; sets CARRY if r9 != 0
+
+		ALIGN 16
+ loop1:
+		mov		rax,qword ptr [rdx + r11 * 8]
+		adc		qword ptr [rcx + r11 * 8], rax
+		lea		r11, [r11+1]
+		dec		r8
+		jnz		loop1
+
+		setc	al
+		movzx	rax, al
+
+		ret
+
+ttmath_adc_x64				ENDP
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_addindexed_x64	PROC
+
+        ; rcx = p1
+        ; rdx = nSize
+        ; r8 = nPos
+        ; r9 = nValue
+
+		xor		rax, rax			; rax = result
+		sub		rdx, r8				; rdx = remaining count of uints
+
+		add		qword ptr [rcx + r8 * 8], r9
+		jc		next1
+
+		ret
+
+next1:
+		mov		r9, 1
+
+		ALIGN 16
+loop1:
+		dec		rdx
+		jz		done_with_cy
+		lea		r8, [r8+1]
+		add		qword ptr [rcx + r8 * 8], r9
+		jc		loop1
+
+		ret
+
+done_with_cy:
+		lea		rax, [rax+1]		; rax = 1
+
+		ret
+
+ttmath_addindexed_x64	ENDP
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_addindexed2_x64	PROC
+
+        ; rcx = p1 (pointer)
+        ; rdx = b  (value size)
+        ; r8 = nPos
+        ; r9 = nValue1
+        ; [esp+0x28] = nValue2
+
+		xor		rax, rax			; return value
+		mov		r11, rcx			; table
+		sub		rdx, r8				; rdx = remaining count of uints
+		mov		r10, [esp+028h]		; r10 = nValue2
+
+		add		qword ptr [r11 + r8 * 8], r9
+		lea		r8, [r8+1]
+		lea		rdx, [rdx-1]
+		adc		qword ptr [r11 + r8 * 8], r10
+		jc		next
+		ret
+
+		ALIGN 16
+loop1:
+		lea		r8, [r8+1]
+		add		qword ptr [r11 + r8 * 8], 1
+		jc		next
+		ret
+
+next:
+		dec		rdx					; does not modify CY too...
+		jnz		loop1
+		lea		rax, [rax+1]
+		ret
+
+ttmath_addindexed2_x64	ENDP
+
+
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+
+ttmath_addvector_x64				PROC
+        ; rcx = ss1
+        ; rdx = ss2
+        ; r8 = ss1_size
+        ; r9 = ss2_size
+        ; [esp+0x28] = result
+
+		mov		r10, [esp+028h]
+		sub		r8, r9
+        xor		r11, r11				; r11=0, cf=0
+
+		ALIGN 16
+ loop1:
+		mov		rax, qword ptr [rcx + r11 * 8]
+		adc		rax, qword ptr [rdx + r11 * 8]
+		mov		qword ptr [r10 + r11 * 8], rax
+		inc		r11
+		dec		r9
+		jnz		loop1
+
+		adc		r9, r9					; r9 has the cf state
+
+		or		r8, r8
+		jz		done
+
+		neg		r9						; setting cf from r9
+		mov		r9, 0					; don't use xor here (cf is used)
+ loop2:
+		mov		rax, qword ptr [rcx + r11 * 8]
+		adc		rax, r9
+		mov		qword ptr [r10 + r11 * 8], rax
+		inc		r11
+		dec		r8
+		jnz		loop2
+
+		adc		r8, r8
+		mov		rax, r8
+		
+		ret
+
+done:
+		mov		rax, r9
+		ret
+
+ttmath_addvector_x64				ENDP
+
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_sbb_x64				PROC
+
+        ; rcx = p1
+        ; rdx = p2
+        ; r8 = nCount
+        ; r9 = nCarry
+
+        xor		rax, rax
+        xor		r11, r11
+        sub		rax, r9				; sets CARRY if r9 != 0
+
+		ALIGN 16
+ loop1:
+		mov		rax,qword ptr [rdx + r11 * 8]
+		sbb		qword ptr [rcx + r11 * 8], rax
+		lea		r11, [r11+1]
+		dec		r8
+		jnz		loop1
+
+		setc	al
+		movzx	rax, al
+
+		ret
+
+ttmath_sbb_x64				ENDP
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_subindexed_x64	PROC
+        ; rcx = p1
+        ; rdx = nSize
+        ; r8 = nPos
+        ; r9 = nValue
+
+		sub		rdx, r8				; rdx = remaining count of uints
+
+		ALIGN 16
+loop1:
+		sub		qword ptr [rcx + r8 * 8], r9
+		jnc		done
+
+		lea		r8, [r8+1]
+		mov		r9, 1
+		dec		rdx
+		jnz		loop1
+
+		mov		rax, 1
+		ret
+
+done:
+		xor		rax, rax
+		ret
+
+ttmath_subindexed_x64	ENDP
+
+
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+;	the same asm code as in addvector_x64 only two instructions 'adc' changed to 'sbb'
+
+ttmath_subvector_x64				PROC
+        ; rcx = ss1
+        ; rdx = ss2
+        ; r8 = ss1_size
+        ; r9 = ss2_size
+        ; [esp+0x28] = result
+
+		mov		r10, [esp+028h]
+		sub		r8, r9
+        xor		r11, r11				; r11=0, cf=0
+
+		ALIGN 16
+ loop1:
+		mov		rax, qword ptr [rcx + r11 * 8]
+		sbb		rax, qword ptr [rdx + r11 * 8]
+		mov		qword ptr [r10 + r11 * 8], rax
+		inc		r11
+		dec		r9
+		jnz		loop1
+
+		adc		r9, r9					; r9 has the cf state
+
+		or		r8, r8
+		jz		done
+
+		neg		r9						; setting cf from r9
+		mov		r9, 0					; don't use xor here (cf is used)
+ loop2:
+		mov		rax, qword ptr [rcx + r11 * 8]
+		sbb		rax, r9
+		mov		qword ptr [r10 + r11 * 8], rax
+		inc		r11
+		dec		r8
+		jnz		loop2
+
+		adc		r8, r8
+		mov		rax, r8
+		
+		ret
+
+done:
+		mov		rax, r9
+		ret
+
+ttmath_subvector_x64				ENDP
+
+
+
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_rcl_x64	PROC
+        ; rcx = p1
+        ; rdx = b
+        ; r8 = nLowestBit
+
+		mov		r11, rcx			; table
+		xor		r10, r10
+		neg		r8					; CY set if r8 <> 0
+
+		ALIGN 16
+loop1:
+		rcl		qword ptr [r11 + r10 * 8], 1
+		lea		r10, [r10+1]
+		dec		rdx
+		jnz		loop1
+
+		setc	al
+		movzx	rax, al
+
+        ret
+
+ttmath_rcl_x64	ENDP
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_rcr_x64	PROC
+        ; rcx = p1
+        ; rdx = nSize
+        ; r8 = nLowestBit
+
+		xor		r10, r10
+		neg		r8					; CY set if r8 <> 0
+
+		ALIGN 16
+loop1:
+		rcr		qword ptr -8[rcx + rdx * 8], 1
+		dec		rdx
+		jnz		loop1
+
+		setc	al
+		movzx	rax, al
+
+        ret
+
+ttmath_rcr_x64	ENDP
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_div_x64	PROC
+
+        ; rcx = &Hi
+        ; rdx = &Lo
+        ; r8 = nDiv
+
+        mov		r11, rcx
+        mov		r10, rdx
+
+        mov		rdx, qword ptr [r11]
+        mov		rax, qword ptr [r10]
+        div		r8
+        mov		qword ptr [r10], rdx ; remainder
+        mov		qword ptr [r11], rax ; value
+
+        ret
+
+ttmath_div_x64	ENDP
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_rcl2_x64	PROC
+        ; rcx = p1
+        ; rdx = nSize
+        ; r8 = bits
+        ; r9 = c
+
+        push	rbx
+
+        mov		r10, rcx	; r10 = p1
+        xor		rax, rax
+
+        mov		rcx, 64
+        sub		rcx, r8
+
+        mov		r11, -1
+        shr		r11, cl		; r11 = mask
+
+		mov		rcx, r8		; rcx = count of bits
+
+		mov		rbx, rax	; rbx = old value = 0
+		or		r9, r9
+		cmovnz	rbx, r11	; if (c) then old value = mask
+
+        mov		r9, rax		; r9 = index (0..nSize-1)
+
+		ALIGN 16
+loop1:
+		rol		qword ptr [r10+r9*8], cl
+		mov		rax, qword ptr [r10+r9*8]
+		and		rax, r11
+		xor		qword ptr [r10+r9*8], rax
+		or		qword ptr [r10+r9*8], rbx
+		mov		rbx, rax
+
+		lea		r9, [r9+1]
+		dec		rdx
+
+		jnz		loop1
+
+		and		rax, 1
+		pop		rbx
+        ret
+
+ttmath_rcl2_x64	ENDP
+
+;----------------------------------------
+
+        ALIGN       8
+
+;----------------------------------------
+
+ttmath_rcr2_x64	PROC
+        ; rcx = p1
+        ; rdx = nSize
+        ; r8 = bits
+        ; r9 = c
+
+        push	rbx
+        mov		r10, rcx	; r10 = p1
+        xor		rax, rax
+
+        mov		rcx, 64
+        sub		rcx, r8
+
+        mov		r11, -1
+        shl		r11, cl		; r11 = mask
+
+		mov		rcx, r8		; rcx = count of bits
+
+		mov		rbx, rax	; rbx = old value = 0
+		or		r9, r9
+		cmovnz	rbx, r11	; if (c) then old value = mask
+
+        mov		r9, rdx		; r9 = index (0..nSize-1)
+		lea		r9, [r9-1]
+
+		ALIGN 16
+loop1:
+		ror		qword ptr [r10+r9*8], cl
+		mov		rax, qword ptr [r10+r9*8]
+		and		rax, r11
+		xor		qword ptr [r10+r9*8], rax
+		or		qword ptr [r10+r9*8], rbx
+		mov		rbx, rax
+
+		lea		r9, [r9-1]
+		dec		rdx
+
+		jnz		loop1
+
+		rol		rax, 1
+		and		rax, 1
+		pop		rbx
+
+        ret
+
+ttmath_rcr2_x64	ENDP
+
+END
Added: sandbox/geometry/boost/geometry/extensions/contrib/ttmath_stub.hpp
==============================================================================
--- (empty file)
+++ sandbox/geometry/boost/geometry/extensions/contrib/ttmath_stub.hpp	2010-07-05 13:06:03 EDT (Mon, 05 Jul 2010)
@@ -0,0 +1,145 @@
+#ifndef TTMATH_STUB
+#define TTMATH_STUB
+
+#include <boost/math/constants/constants.hpp>
+
+
+#include <ttmath/ttmath.h>
+namespace ttmath
+{
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> sqrt(Big<Mantissa, Exponent> const& v)
+    {
+        return Sqrt(v);
+    }
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> abs(Big<Mantissa, Exponent> const& v)
+    {
+        return Abs(v);
+    }
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> ceil(Big<Mantissa, Exponent> const& v)
+    {
+        return Ceil(v);
+    }
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> floor(Big<Mantissa, Exponent> const& v)
+    {
+        return Floor(v);
+    }
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> asin(Big<Mantissa, Exponent> const& v)
+    {
+        return ASin(v);
+    }
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> sin(Big<Mantissa, Exponent> const& v)
+    {
+        return Sin(v);
+    }
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> cos(Big<Mantissa, Exponent> const& v)
+    {
+        return Cos(v);
+    }
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> tan(Big<Mantissa, Exponent> const& v)
+    {
+        return Tan(v);
+    }
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> atan(Big<Mantissa, Exponent> const& v)
+    {
+        return ATan(v);
+    }
+
+
+    template <uint Mantissa, uint Exponent>
+    inline Big<Mantissa, Exponent> atan2(Big<Mantissa, Exponent> const& y, Big<Mantissa, Exponent> const& x)
+    {
+        // return ATan2(y, 2); does not (yet) exist in ttmath...
+
+        // See http://en.wikipedia.org/wiki/Atan2
+
+        Big<Mantissa, Exponent> const zero(0);
+        Big<Mantissa, Exponent> const two(2);
+
+        if (y == zero)
+        {
+            // return x >= 0 ? 0 : pi and pi=2*arccos(0)
+            return x >= zero ? zero : two * ACos(zero);
+        }
+
+        return two * ATan((sqrt(x * x + y * y) - x) / y);
+    }
+
+}
+
+// Specific structure implementing constructor
+// (WHICH IS NECESSARY FOR Boost.Geometry because it enables using T() !! )
+struct ttmath_big : ttmath::Big<1,4>
+{
+    ttmath_big(double v = 0)
+        : ttmath::Big<1,4>(v)
+    {}
+    ttmath_big(ttmath::Big<1,4> const& v)
+        : ttmath::Big<1,4>(v)
+    {}
+
+    /*
+    inline operator double() const
+    {
+        return atof(this->ToString().c_str());
+    }
+
+    inline operator int() const
+    {
+        return atol(ttmath::Round(*this).ToString().c_str());
+    }
+    */
+};
+
+namespace boost{ namespace math { namespace constants
+{
+    // Workaround for boost::math::constants::pi: 
+    // 1) lexical cast -> stack overflow and
+    // 2) because it is implemented as a function, generic implementation not possible
+
+    template <ttmath::uint Mantissa, ttmath::uint Exponent>
+    inline ttmath::Big<Mantissa, Exponent> ttmath_pi()
+    {
+        static ttmath::Big<Mantissa, Exponent> const the_pi("3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196");
+        return the_pi;
+    }
+
+
+    template <> inline ttmath::Big<1,4> pi<ttmath::Big<1,4> >(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC( (ttmath::Big<1,4>) ))
+    {
+        return ttmath_pi<1,4>();
+    }
+    template <> inline ttmath::Big<1,8> pi<ttmath::Big<1,8> >(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC( (ttmath::Big<1,8>) ))
+    {
+        return ttmath_pi<1,8>();
+    }
+
+    // and so on...
+    // or fix lexical_cast but probably has the same problem
+
+
+    template <> inline ttmath_big pi<ttmath_big >(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(ttmath_big))
+    {
+        return ttmath_pi<1,4>();
+    }
+
+}}}
+
+
+#endif