2007-01-21 21:02:44 +01:00
|
|
|
/*
|
2007-01-22 21:25:45 +01:00
|
|
|
* This file is a part of TTMath Mathematical Library
|
2007-01-21 21:02:44 +01:00
|
|
|
* and is distributed under the (new) BSD licence.
|
|
|
|
* Author: Tomasz Sowa <t.sowa@slimaczek.pl>
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2008-06-18 02:33:05 +02:00
|
|
|
* Copyright (c) 2006-2008, Tomasz Sowa
|
2007-01-21 21:02:44 +01:00
|
|
|
* 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>
|
|
|
|
*/
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
#include <iostream>
|
|
|
|
#include <iomanip>
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
#include "ttmathtypes.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
/*!
|
|
|
|
\brief a namespace for the TTMath library
|
|
|
|
*/
|
2007-01-21 21:02:44 +01:00
|
|
|
namespace ttmath
|
|
|
|
{
|
|
|
|
|
|
|
|
/*!
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
\brief UInt implements a big integer value without a sign
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-02-05 18:40:23 +01:00
|
|
|
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
|
2007-01-21 21:02:44 +01:00
|
|
|
value_size = 1,2,3,4,5,6....
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
class UInt
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
buffer for the integer value
|
|
|
|
table[0] - the lowest word of the value
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
uint table[value_size];
|
|
|
|
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
/*!
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
void PrintTable(std::ostream & 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::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
this method returns the size of the table
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
uint Size() const
|
|
|
|
{
|
|
|
|
return value_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
this method sets zero
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
void SetZero()
|
|
|
|
{
|
2008-06-18 02:33:05 +02:00
|
|
|
// in the future here can be 'memset'
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
for(uint i=0 ; i<value_size ; ++i)
|
|
|
|
table[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
this method sets one
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
void SetOne()
|
|
|
|
{
|
|
|
|
SetZero();
|
|
|
|
table[0] = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method sets the max value which this class can hold
|
|
|
|
(all bits will be one)
|
|
|
|
*/
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
void SetMax()
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
for(uint i=0 ; i<value_size ; ++i)
|
2007-01-22 21:25:45 +01:00
|
|
|
table[i] = TTMATH_UINT_MAX_VALUE;
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method sets the min value which this class can hold
|
|
|
|
(for an unsigned integer value the zero is the smallest value)
|
|
|
|
*/
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
void SetMin()
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
SetZero();
|
|
|
|
}
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
#ifdef TTMATH_PLATFORM32
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
/*!
|
2007-01-29 18:58:18 +01:00
|
|
|
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)
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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
|
2007-01-29 18:58:18 +01:00
|
|
|
(this rounding isn't a perfect rounding -- look at the description below)
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
and if temp_table_len is smaller than value_size we'll clear the rest words
|
2007-02-24 19:59:05 +01:00
|
|
|
in the table
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
void SetFromTable(const uint * temp_table, uint temp_table_len)
|
|
|
|
{
|
|
|
|
uint temp_table_index = 0;
|
2007-01-29 18:58:18 +01:00
|
|
|
sint i; // 'i' with a sign
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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 )
|
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
if( (temp_table[temp_table_index] & TTMATH_UINT_HIGHEST_BIT) != 0 )
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
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
|
2007-01-29 18:58:18 +01:00
|
|
|
we don't use Add() or AddTwoInts() because these methods
|
2007-01-21 21:02:44 +01:00
|
|
|
can set a carry and then there'll be a small problem
|
|
|
|
for optimization
|
|
|
|
*/
|
2007-02-24 19:59:05 +01:00
|
|
|
if( table[0] != TTMATH_UINT_MAX_VALUE )
|
2007-01-21 21:02:44 +01:00
|
|
|
++table[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
// cleaning the rest of the mantissa
|
2007-01-21 21:02:44 +01:00
|
|
|
for( ; i>=0 ; --i)
|
|
|
|
table[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* basic mathematic functions
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2007-02-24 19:59:05 +01:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
adding ss2 to the this and adding carry if it's defined
|
2007-01-21 21:02:44 +01:00
|
|
|
(this = this + ss2 + c)
|
|
|
|
|
|
|
|
c must be zero or one (might be a bigger value than 1)
|
2008-06-18 02:33:05 +02:00
|
|
|
function returns carry (1) (if it has been)
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
uint Add(const UInt<value_size> & ss2, uint c=0)
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
register uint b = value_size;
|
2007-01-21 21:02:44 +01:00
|
|
|
register uint * p1 = table;
|
|
|
|
register uint * p2 = const_cast<uint*>(ss2.table);
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef __GNUC__
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
// this part might be compiled with for example visual c
|
2008-10-25 22:05:51 +02:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push eax
|
|
|
|
push ebx
|
|
|
|
push ecx
|
|
|
|
push edx
|
2008-10-25 22:05:51 +02:00
|
|
|
push esi
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
mov ecx,[b]
|
|
|
|
|
|
|
|
mov ebx,[p1]
|
2008-10-25 22:05:51 +02:00
|
|
|
mov esi,[p2]
|
|
|
|
|
|
|
|
xor eax,eax // eax=0
|
|
|
|
mov edx,eax // edx=0
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
sub eax,[c] // CF=c
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
p:
|
2008-10-25 22:05:51 +02:00
|
|
|
mov eax,[esi+edx*4]
|
|
|
|
adc [ebx+edx*4],eax
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
inc edx
|
2008-10-22 20:56:04 +02:00
|
|
|
dec ecx
|
2008-10-17 11:57:36 +02:00
|
|
|
jnz p
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
setc al
|
2008-10-17 11:57:36 +02:00
|
|
|
movzx edx, al
|
|
|
|
mov [c], edx
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
pop esi
|
2007-01-21 21:02:44 +01:00
|
|
|
pop edx
|
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
pop eax
|
|
|
|
}
|
2008-10-25 22:05:51 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
// this part should be compiled with gcc
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"push %%ecx \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"xorl %%eax, %%eax \n"
|
|
|
|
"movl %%eax, %%edx \n"
|
|
|
|
"subl %%edi, %%eax \n"
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"1: \n"
|
|
|
|
"movl (%%esi,%%edx,4),%%eax \n"
|
|
|
|
"adcl %%eax, (%%ebx,%%edx,4) \n"
|
|
|
|
|
|
|
|
"incl %%edx \n"
|
|
|
|
"decl %%ecx \n"
|
|
|
|
"jnz 1b \n"
|
2008-10-17 11:57:36 +02:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"setc %%al \n"
|
|
|
|
"movzx %%al,%%edx \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"pop %%ecx \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
: "=d" (c)
|
|
|
|
: "D" (c), "c" (b), "b" (p1), "S" (p2)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "%eax", "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
return c;
|
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
adding one word (at a specific position)
|
|
|
|
and returning a carry (if it has been)
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
of course if there was a carry from table[2] it would be returned
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
uint AddInt(uint value, uint index = 0)
|
|
|
|
{
|
|
|
|
register uint b = value_size;
|
|
|
|
register uint * p1 = table;
|
|
|
|
register uint c;
|
|
|
|
|
|
|
|
#ifndef __GNUC__
|
2008-10-25 22:05:51 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push eax
|
|
|
|
push ebx
|
|
|
|
push ecx
|
|
|
|
push edx
|
|
|
|
|
|
|
|
mov ecx, [b]
|
|
|
|
sub ecx, [index]
|
|
|
|
|
|
|
|
mov edx, [index]
|
2008-10-25 22:05:51 +02:00
|
|
|
mov ebx, [p1]
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
mov eax, [value]
|
2008-10-17 11:57:36 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
p:
|
2008-10-25 22:05:51 +02:00
|
|
|
add [ebx+edx*4], eax
|
|
|
|
jnc end
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
mov eax, 1
|
|
|
|
inc edx
|
|
|
|
dec ecx
|
2008-10-17 11:57:36 +02:00
|
|
|
jnz p
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
end:
|
|
|
|
setc al
|
2008-10-17 11:57:36 +02:00
|
|
|
movzx edx, al
|
|
|
|
mov [c], edx
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
pop edx
|
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
pop eax
|
|
|
|
}
|
2008-10-25 22:05:51 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"push %%eax \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
"push %%ecx \n"
|
|
|
|
|
|
|
|
"subl %%edx, %%ecx \n"
|
|
|
|
|
|
|
|
"1: \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"addl %%eax, (%%ebx,%%edx,4) \n"
|
|
|
|
"jnc 2f \n"
|
|
|
|
|
|
|
|
"movl $1, %%eax \n"
|
|
|
|
"incl %%edx \n"
|
|
|
|
"decl %%ecx \n"
|
2008-10-17 11:57:36 +02:00
|
|
|
"jnz 1b \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"2: \n"
|
|
|
|
"setc %%al \n"
|
|
|
|
"movzx %%al, %%edx \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
"pop %%ecx \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"pop %%eax \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
: "=d" (c)
|
|
|
|
: "a" (value), "c" (b), "0" (index), "b" (p1)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
adding only two unsigned words to the existing value
|
2007-01-21 21:02:44 +01:00
|
|
|
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.)
|
|
|
|
*/
|
2007-02-05 18:40:23 +01:00
|
|
|
uint AddTwoInts(uint x2, uint x1, uint index)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
register uint b = value_size;
|
2007-01-21 21:02:44 +01:00
|
|
|
register uint * p1 = table;
|
|
|
|
register uint c;
|
|
|
|
|
|
|
|
#ifndef __GNUC__
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push eax
|
|
|
|
push ebx
|
|
|
|
push ecx
|
|
|
|
push edx
|
|
|
|
|
|
|
|
mov ecx, [b]
|
|
|
|
sub ecx, [index]
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
mov ebx, [p1]
|
2007-01-21 21:02:44 +01:00
|
|
|
mov edx, [index]
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
mov eax, [x1]
|
|
|
|
add [ebx+edx*4], eax
|
|
|
|
inc edx
|
2007-01-21 21:02:44 +01:00
|
|
|
dec ecx
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
mov eax, [x2]
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
p:
|
2008-10-25 22:05:51 +02:00
|
|
|
adc [ebx+edx*4], eax
|
2007-01-21 21:02:44 +01:00
|
|
|
jnc end
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
mov eax, 0
|
|
|
|
inc edx
|
|
|
|
dec ecx
|
|
|
|
jnz p
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
end:
|
2008-10-17 11:57:36 +02:00
|
|
|
setc al
|
|
|
|
movzx edx, al
|
|
|
|
mov [c], edx
|
2008-10-25 22:05:51 +02:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
pop edx
|
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
pop eax
|
2008-10-25 22:05:51 +02:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
|
|
|
"push %%ecx \n"
|
|
|
|
"push %%edx \n"
|
|
|
|
|
|
|
|
"subl %%edx, %%ecx \n"
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"addl %%esi, (%%ebx,%%edx,4) \n"
|
|
|
|
"incl %%edx \n"
|
|
|
|
"decl %%ecx \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
"1: \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"adcl %%eax, (%%ebx,%%edx,4) \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
"jnc 2f \n"
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"mov $0, %%eax \n"
|
|
|
|
"incl %%edx \n"
|
|
|
|
"decl %%ecx \n"
|
|
|
|
"jnz 1b \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
"2: \n"
|
2008-10-17 11:57:36 +02:00
|
|
|
"setc %%al \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"movzx %%al, %%eax \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
"pop %%edx \n"
|
|
|
|
"pop %%ecx \n"
|
|
|
|
|
|
|
|
: "=a" (c)
|
2008-10-25 22:05:51 +02:00
|
|
|
: "c" (b), "d" (index), "b" (p1), "S" (x1), "0" (x2)
|
2007-01-21 21:02:44 +01:00
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
subtracting ss2 from the 'this' and subtracting
|
2007-01-29 18:58:18 +01:00
|
|
|
carry if it has been defined
|
2007-01-21 21:02:44 +01:00
|
|
|
(this = this - ss2 - c)
|
|
|
|
|
|
|
|
c must be zero or one (might be a bigger value than 1)
|
2008-06-18 02:33:05 +02:00
|
|
|
function returns carry (1) (if it has been)
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
uint Sub(const UInt<value_size> & ss2, uint c=0)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
register uint b = value_size;
|
2007-01-21 21:02:44 +01:00
|
|
|
register uint * p1 = table;
|
|
|
|
register uint * p2 = const_cast<uint*>(ss2.table);
|
|
|
|
|
|
|
|
#ifndef __GNUC__
|
|
|
|
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push eax
|
|
|
|
push ebx
|
|
|
|
push ecx
|
|
|
|
push edx
|
2008-10-29 22:54:27 +01:00
|
|
|
push esi
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
mov ecx,[b]
|
|
|
|
|
|
|
|
mov ebx,[p1]
|
2008-10-29 22:54:27 +01:00
|
|
|
mov esi,[p2]
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
xor eax, eax
|
|
|
|
mov edx, eax
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
sub eax, [c]
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
p:
|
|
|
|
mov eax, [esi+edx*4]
|
|
|
|
sbb [ebx+edx*4], eax
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
inc edx
|
2008-10-29 22:54:27 +01:00
|
|
|
dec ecx
|
|
|
|
jnz p
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
setc al
|
|
|
|
movzx edx, al
|
|
|
|
mov [c], edx
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
pop esi
|
2007-01-21 21:02:44 +01:00
|
|
|
pop edx
|
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
pop eax
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"push %%ecx \n"
|
|
|
|
|
|
|
|
"xorl %%eax, %%eax \n"
|
|
|
|
"movl %%eax, %%edx \n"
|
|
|
|
"subl %%edi, %%eax \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"1: \n"
|
|
|
|
"movl (%%esi,%%edx,4),%%eax \n"
|
|
|
|
"sbbl %%eax, (%%ebx,%%edx,4) \n"
|
|
|
|
|
|
|
|
"incl %%edx \n"
|
|
|
|
"decl %%ecx \n"
|
|
|
|
"jnz 1b \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"setc %%al \n"
|
|
|
|
"movzx %%al,%%edx \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"pop %%ecx \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
: "=d" (c)
|
|
|
|
: "D" (c), "c" (b), "b" (p1), "S" (p2)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "%eax", "cc", "memory" );
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2007-01-29 18:58:18 +01:00
|
|
|
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[3] it would be returned
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
uint SubInt(uint value, uint index = 0)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
register uint b = value_size;
|
|
|
|
register uint * p1 = table;
|
|
|
|
register uint c;
|
|
|
|
|
|
|
|
#ifndef __GNUC__
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push eax
|
|
|
|
push ebx
|
|
|
|
push ecx
|
|
|
|
push edx
|
|
|
|
|
|
|
|
mov ecx, [b]
|
|
|
|
sub ecx, [index]
|
|
|
|
|
|
|
|
mov edx, [index]
|
2008-10-29 22:54:27 +01:00
|
|
|
mov ebx, [p1]
|
|
|
|
|
|
|
|
mov eax, [value]
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
p:
|
2008-10-29 22:54:27 +01:00
|
|
|
sub [ebx+edx*4], eax
|
2007-01-29 18:58:18 +01:00
|
|
|
jnc end
|
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov eax, 1
|
|
|
|
inc edx
|
|
|
|
dec ecx
|
|
|
|
jnz p
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
end:
|
2008-10-29 22:54:27 +01:00
|
|
|
setc al
|
|
|
|
movzx edx, al
|
|
|
|
mov [c], edx
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
pop edx
|
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
pop eax
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"push %%eax \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
"push %%ecx \n"
|
|
|
|
|
|
|
|
"subl %%edx, %%ecx \n"
|
|
|
|
|
|
|
|
"1: \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"subl %%eax, (%%ebx,%%edx,4) \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
"jnc 2f \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
|
|
|
|
"movl $1, %%eax \n"
|
|
|
|
"incl %%edx \n"
|
|
|
|
"decl %%ecx \n"
|
|
|
|
"jnz 1b \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
"2: \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"setc %%al \n"
|
|
|
|
"movzx %%al, %%edx \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
"pop %%ecx \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"pop %%eax \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
: "=d" (c)
|
|
|
|
: "a" (value), "c" (b), "0" (index), "b" (p1)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
/*!
|
|
|
|
this method adds one to the existing value
|
|
|
|
*/
|
|
|
|
uint AddOne()
|
|
|
|
{
|
|
|
|
return AddInt(1);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method subtracts one from the existing value
|
|
|
|
*/
|
|
|
|
uint SubOne()
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
return SubInt(1);
|
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
private:
|
|
|
|
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
#ifdef TTMATH_PLATFORM32
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
/*!
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
uint Rcl2_one(uint c)
|
|
|
|
{
|
|
|
|
register sint b = value_size;
|
|
|
|
register uint * p1 = table;
|
|
|
|
|
|
|
|
#ifndef __GNUC__
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push ebx
|
|
|
|
push ecx
|
|
|
|
push edx
|
|
|
|
|
|
|
|
mov ebx, [p1]
|
|
|
|
|
|
|
|
xor edx, edx
|
|
|
|
mov ecx, edx
|
|
|
|
sub ecx, [c]
|
|
|
|
|
|
|
|
mov ecx, [b]
|
|
|
|
|
|
|
|
p:
|
|
|
|
rcl dword ptr [ebx+edx*4], 1
|
|
|
|
|
|
|
|
inc edx
|
|
|
|
dec ecx
|
|
|
|
jnz p
|
|
|
|
|
|
|
|
setc dl
|
|
|
|
movzx edx, dl
|
|
|
|
mov [c], edx
|
|
|
|
|
|
|
|
|
|
|
|
pop edx
|
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
|
|
|
"push %%edx \n"
|
|
|
|
"push %%ecx \n"
|
|
|
|
|
|
|
|
"xorl %%edx, %%edx \n" // edx=0
|
|
|
|
"neg %%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"
|
|
|
|
|
|
|
|
"setc %%al \n"
|
|
|
|
"movzx %%al, %%eax \n"
|
|
|
|
|
|
|
|
"pop %%ecx \n"
|
|
|
|
"pop %%edx \n"
|
|
|
|
|
|
|
|
: "=a" (c)
|
|
|
|
: "0" (c), "c" (b), "b" (p1)
|
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
uint Rcr2_one(uint c)
|
|
|
|
{
|
|
|
|
register sint b = value_size;
|
|
|
|
register uint * p1 = table;
|
|
|
|
|
|
|
|
#ifndef __GNUC__
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push ebx
|
|
|
|
push ecx
|
|
|
|
|
|
|
|
mov ebx, [p1]
|
|
|
|
|
|
|
|
xor ecx, ecx
|
|
|
|
sub ecx, [c]
|
|
|
|
|
|
|
|
mov ecx, [b]
|
|
|
|
|
|
|
|
p:
|
|
|
|
rcr dword ptr [ebx+ecx*4-4], 1
|
|
|
|
|
|
|
|
dec ecx
|
|
|
|
jnz p
|
|
|
|
|
|
|
|
setc dl
|
|
|
|
movzx edx, dl
|
|
|
|
mov [c], edx
|
|
|
|
|
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
|
|
|
"push %%ecx \n"
|
|
|
|
|
|
|
|
"neg %%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"
|
|
|
|
|
|
|
|
"setc %%al \n"
|
|
|
|
"movzx %%al, %%eax \n"
|
|
|
|
|
|
|
|
"pop %%ecx \n"
|
|
|
|
|
|
|
|
: "=a" (c)
|
|
|
|
: "0" (c), "c" (b), "b" (p1)
|
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
2007-04-12 00:14:17 +02:00
|
|
|
this method moves all bits into the left hand side
|
|
|
|
return value <- this <- c
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
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
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
2007-04-12 00:14:17 +02:00
|
|
|
uint Rcl2(uint bits, uint c)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-04-12 00:14:17 +02:00
|
|
|
if( bits == 0 )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
register sint b = value_size;
|
2007-01-21 21:02:44 +01:00
|
|
|
register uint * p1 = table;
|
2008-10-29 22:54:27 +01:00
|
|
|
register uint mask;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
#ifndef __GNUC__
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push eax
|
|
|
|
push ebx
|
|
|
|
push ecx
|
2007-04-12 00:14:17 +02:00
|
|
|
push edx
|
2008-10-29 22:54:27 +01:00
|
|
|
push esi
|
|
|
|
push edi
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov edi, [b]
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov ecx, 32
|
|
|
|
sub ecx, [bits]
|
|
|
|
mov edx, -1
|
|
|
|
shr edx, cl
|
|
|
|
mov [mask], edx
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov ecx, [bits]
|
|
|
|
mov ebx, [p1]
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
xor edx, edx // edx = 0
|
|
|
|
mov esi, edx // old value = 0
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov eax, [c]
|
|
|
|
or eax, eax
|
|
|
|
cmovnz esi, [mask] // if c then old value = mask
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
p:
|
|
|
|
rol dword ptr [ebx+edx*4], cl
|
|
|
|
|
|
|
|
mov eax, [ebx+edx*4]
|
|
|
|
and eax, [mask]
|
|
|
|
xor [ebx+edx*4], eax // clearing bits
|
|
|
|
or [ebx+edx*4], esi // saving old value
|
|
|
|
mov esi, eax
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
inc edx
|
|
|
|
dec edi
|
|
|
|
jnz p
|
2008-10-17 11:57:36 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
and eax, 1
|
|
|
|
mov [c], eax
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
pop edi
|
|
|
|
pop esi
|
2007-04-12 00:14:17 +02:00
|
|
|
pop edx
|
2007-01-21 21:02:44 +01:00
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
pop eax
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
2008-10-17 11:57:36 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"push %%edx \n"
|
|
|
|
"push %%esi \n"
|
|
|
|
"push %%edi \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"movl %%ecx, %%esi \n"
|
|
|
|
"movl $32, %%ecx \n"
|
|
|
|
"subl %%esi, %%ecx \n"
|
|
|
|
"movl $-1, %%edx \n"
|
|
|
|
"shrl %%cl, %%edx \n"
|
|
|
|
"movl %%edx, %[amask] \n"
|
|
|
|
"movl %%esi, %%ecx \n"
|
|
|
|
|
|
|
|
"xorl %%edx, %%edx \n"
|
|
|
|
"movl %%edx, %%esi \n"
|
|
|
|
|
|
|
|
"orl %%eax, %%eax \n"
|
|
|
|
"cmovnz %[amask], %%esi \n"
|
|
|
|
|
|
|
|
"1: \n"
|
|
|
|
"roll %%cl, (%%ebx,%%edx,4) \n"
|
|
|
|
|
|
|
|
"movl (%%ebx,%%edx,4), %%eax \n"
|
|
|
|
"andl %[amask], %%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"
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"pop %%edi \n"
|
|
|
|
"pop %%esi \n"
|
|
|
|
"pop %%edx \n"
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
: "=a" (c)
|
|
|
|
: "0" (c), "D" (b), "b" (p1), "c" (bits), [amask] "m" (mask)
|
|
|
|
: "cc", "memory" );
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2007-04-12 00:14:17 +02:00
|
|
|
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
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
for example:
|
|
|
|
let this is 000000010
|
|
|
|
after Rcr2(2, 1) there'll be 110000000 and Rcr2 returns 1
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
2007-04-12 00:14:17 +02:00
|
|
|
uint Rcr2(uint bits, uint c)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-04-12 00:14:17 +02:00
|
|
|
if( bits == 0 )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
register sint b = value_size;
|
2007-01-21 21:02:44 +01:00
|
|
|
register uint * p1 = table;
|
2008-10-29 22:54:27 +01:00
|
|
|
register uint mask;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
#ifndef __GNUC__
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push eax
|
|
|
|
push ebx
|
|
|
|
push ecx
|
2007-04-12 00:14:17 +02:00
|
|
|
push edx
|
2008-10-29 22:54:27 +01:00
|
|
|
push esi
|
|
|
|
push edi
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov edi, [b]
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov ecx, 32
|
|
|
|
sub ecx, [bits]
|
|
|
|
mov edx, -1
|
|
|
|
shl edx, cl
|
|
|
|
mov [mask], edx
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov ecx, [bits]
|
|
|
|
mov ebx, [p1]
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
xor edx, edx // edx = 0
|
|
|
|
mov esi, edx // old value = 0
|
|
|
|
add edx, edi
|
|
|
|
dec edx // edx - is pointing at the last word
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov eax, [c]
|
|
|
|
or eax, eax
|
|
|
|
cmovnz esi, [mask] // if c then old value = mask
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
p:
|
|
|
|
ror dword ptr [ebx+edx*4], cl
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
mov eax, [ebx+edx*4]
|
|
|
|
and eax, [mask]
|
|
|
|
xor [ebx+edx*4], eax // clearing bits
|
|
|
|
or [ebx+edx*4], esi // saving old value
|
|
|
|
mov esi, eax
|
|
|
|
|
|
|
|
dec edx
|
|
|
|
dec edi
|
|
|
|
jnz p
|
2008-10-17 11:57:36 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
rol eax, 1 // 31bit will be first
|
|
|
|
and eax, 1
|
|
|
|
mov [c], eax
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
pop edi
|
|
|
|
pop esi
|
2007-04-12 00:14:17 +02:00
|
|
|
pop edx
|
2007-01-21 21:02:44 +01:00
|
|
|
pop ecx
|
|
|
|
pop ebx
|
|
|
|
pop eax
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"push %%edx \n"
|
|
|
|
"push %%esi \n"
|
|
|
|
"push %%edi \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"movl %%ecx, %%esi \n"
|
|
|
|
"movl $32, %%ecx \n"
|
|
|
|
"subl %%esi, %%ecx \n"
|
|
|
|
"movl $-1, %%edx \n"
|
|
|
|
"shll %%cl, %%edx \n"
|
|
|
|
"movl %%edx, %[amask] \n"
|
|
|
|
"movl %%esi, %%ecx \n"
|
|
|
|
|
|
|
|
"xorl %%edx, %%edx \n"
|
|
|
|
"movl %%edx, %%esi \n"
|
|
|
|
"addl %%edi, %%edx \n"
|
|
|
|
"decl %%edx \n"
|
|
|
|
|
|
|
|
"orl %%eax, %%eax \n"
|
|
|
|
"cmovnz %[amask], %%esi \n"
|
|
|
|
|
|
|
|
"1: \n"
|
|
|
|
"rorl %%cl, (%%ebx,%%edx,4) \n"
|
|
|
|
|
|
|
|
"movl (%%ebx,%%edx,4), %%eax \n"
|
|
|
|
"andl %[amask], %%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"
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"pop %%edi \n"
|
|
|
|
"pop %%esi \n"
|
|
|
|
"pop %%edx \n"
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
: "=a" (c)
|
|
|
|
: "0" (c), "D" (b), "b" (p1), "c" (bits), [amask] "m" (mask)
|
|
|
|
: "cc", "memory" );
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2007-07-23 01:20:09 +02:00
|
|
|
/*!
|
|
|
|
an auxiliary method for moving bits into the left hand side
|
|
|
|
|
|
|
|
this method moves only words
|
|
|
|
*/
|
2008-10-31 21:43:08 +01:00
|
|
|
void RclMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c)
|
|
|
|
{
|
|
|
|
rest_bits = sint(bits % TTMATH_BITS_PER_UINT);
|
|
|
|
sint all_words = sint(bits / TTMATH_BITS_PER_UINT);
|
|
|
|
uint mask = ( c ) ? TTMATH_UINT_MAX_VALUE : 0;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
|
|
|
|
if( all_words >= sint(value_size) )
|
|
|
|
{
|
2008-10-31 21:43:08 +01:00
|
|
|
if( all_words == value_size && rest_bits == 0 )
|
2007-04-12 00:14:17 +02:00
|
|
|
last_c = table[0] & 1;
|
|
|
|
|
2008-10-31 21:43:08 +01:00
|
|
|
// clearing
|
|
|
|
for(uint i = 0 ; i<value_size ; ++i)
|
|
|
|
table[i] = mask;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
rest_bits = 0;
|
|
|
|
}
|
2008-10-31 21:43:08 +01:00
|
|
|
else
|
|
|
|
if( all_words > 0 )
|
2007-04-12 00:14:17 +02:00
|
|
|
{
|
2008-10-31 21:43:08 +01:00
|
|
|
// 0 < all_words < value_size
|
|
|
|
|
|
|
|
sint first, second;
|
2007-04-12 00:14:17 +02:00
|
|
|
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];
|
|
|
|
|
2008-10-31 21:43:08 +01:00
|
|
|
// setting the rest to 'c'
|
2007-04-12 00:14:17 +02:00
|
|
|
for( ; first>=0 ; --first )
|
|
|
|
table[first] = mask;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
moving all bits into the left side 'bits' times
|
2007-01-21 21:02:44 +01:00
|
|
|
return value <- this <- C
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
|
2007-01-21 21:02:44 +01:00
|
|
|
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
|
|
|
|
*/
|
2007-04-12 00:14:17 +02:00
|
|
|
uint Rcl(uint bits, uint c=0)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2008-10-31 21:43:08 +01:00
|
|
|
uint last_c = 0;
|
2007-04-12 00:14:17 +02:00
|
|
|
uint rest_bits = bits;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
if( bits == 0 )
|
|
|
|
return 0;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
if( bits >= TTMATH_BITS_PER_UINT )
|
2008-10-31 21:43:08 +01:00
|
|
|
RclMoveAllWords(rest_bits, last_c, bits, c);
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
if( rest_bits == 0 )
|
|
|
|
return last_c;
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
// rest_bits is from 1 to TTMATH_BITS_PER_UINT-1 now
|
|
|
|
if( rest_bits == 1 )
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2008-10-31 00:38:24 +01:00
|
|
|
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);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
2008-10-31 00:38:24 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
last_c = Rcl2(rest_bits, c);
|
|
|
|
}
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
return last_c;
|
|
|
|
}
|
|
|
|
|
2007-07-23 01:20:09 +02:00
|
|
|
private:
|
|
|
|
|
|
|
|
/*!
|
|
|
|
an auxiliary method for moving bits into the right hand side
|
|
|
|
|
|
|
|
this method moves only words
|
|
|
|
*/
|
2008-10-31 21:43:08 +01:00
|
|
|
void RcrMoveAllWords(uint & rest_bits, uint & last_c, uint bits, uint c)
|
2007-07-23 01:20:09 +02:00
|
|
|
{
|
2008-10-31 21:43:08 +01:00
|
|
|
rest_bits = sint(bits % TTMATH_BITS_PER_UINT);
|
|
|
|
sint all_words = sint(bits / TTMATH_BITS_PER_UINT);
|
|
|
|
uint mask = c ? TTMATH_UINT_MAX_VALUE : 0;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
|
|
|
|
if( all_words >= sint(value_size) )
|
|
|
|
{
|
2008-10-31 21:43:08 +01:00
|
|
|
if( all_words == value_size && rest_bits == 0 )
|
2007-04-12 00:14:17 +02:00
|
|
|
last_c = (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) ? 1 : 0;
|
|
|
|
|
2008-10-31 21:43:08 +01:00
|
|
|
// clearing
|
|
|
|
for(uint i = 0 ; i<value_size ; ++i)
|
|
|
|
table[i] = mask;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
rest_bits = 0;
|
|
|
|
}
|
2008-10-31 21:43:08 +01:00
|
|
|
else if( all_words > 0 )
|
2007-04-12 00:14:17 +02:00
|
|
|
{
|
2008-10-31 21:43:08 +01:00
|
|
|
// 0 < all_words < value_size
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2008-10-31 21:43:08 +01:00
|
|
|
uint first, second;
|
2007-04-12 00:14:17 +02:00
|
|
|
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];
|
|
|
|
|
2008-10-31 21:43:08 +01:00
|
|
|
// setting the rest to 'c'
|
2007-04-12 00:14:17 +02:00
|
|
|
for( ; first<value_size ; ++first )
|
|
|
|
table[first] = mask;
|
|
|
|
}
|
2007-07-23 01:20:09 +02:00
|
|
|
}
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
public:
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
moving all bits into the right side 'bits' times
|
2007-01-21 21:02:44 +01:00
|
|
|
c -> this -> return value
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
bits is from a range of <0, man * TTMATH_BITS_PER_UINT>
|
2007-01-21 21:02:44 +01:00
|
|
|
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
|
|
|
|
*/
|
2007-04-12 00:14:17 +02:00
|
|
|
uint Rcr(uint bits, uint c=0)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-04-12 00:14:17 +02:00
|
|
|
uint last_c = 0;
|
|
|
|
uint rest_bits = bits;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
if( bits == 0 )
|
|
|
|
return 0;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
if( bits >= TTMATH_BITS_PER_UINT )
|
2008-10-31 21:43:08 +01:00
|
|
|
RcrMoveAllWords(rest_bits, last_c, bits, c);
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
if( rest_bits == 0 )
|
|
|
|
return last_c;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
// 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);
|
2007-04-12 00:14:17 +02:00
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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
|
2007-01-29 18:58:18 +01:00
|
|
|
sint a;
|
2007-01-21 21:02:44 +01:00
|
|
|
for(a=value_size-1 ; a>=0 && table[a]==0 ; --a);
|
|
|
|
|
|
|
|
if( a < 0 )
|
|
|
|
{
|
|
|
|
// there's a value zero
|
|
|
|
return moving;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( a != value_size-1 )
|
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
moving += ( value_size-1 - a ) * TTMATH_BITS_PER_UINT;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
// moving all words
|
2007-01-29 18:58:18 +01:00
|
|
|
sint i;
|
|
|
|
for(i=value_size-1 ; a>=0 ; --i, --a)
|
2007-01-21 21:02:44 +01:00
|
|
|
table[i] = table[a];
|
|
|
|
|
|
|
|
// setting the rest word to zero
|
|
|
|
for(; i>=0 ; --i)
|
|
|
|
table[i] = 0;
|
|
|
|
}
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
uint moving2 = FindLeadingBitInWord( table[value_size-1] );
|
|
|
|
// moving2 is different from -1 because the value table[value_size-1]
|
|
|
|
// is not zero
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
moving2 = TTMATH_BITS_PER_UINT - moving2 - 1;
|
|
|
|
Rcl(moving2);
|
|
|
|
|
|
|
|
return moving + moving2;
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
#ifdef TTMATH_PLATFORM32
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
this method returns the number of the highest set bit in one 32-bit word
|
|
|
|
if the 'x' is zero this method returns '-1'
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
static sint FindLeadingBitInWord(uint x)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
register sint result;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
#ifndef __GNUC__
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push eax
|
2008-10-17 11:57:36 +02:00
|
|
|
push edx
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2008-10-17 11:57:36 +02:00
|
|
|
and edx,-1
|
2007-01-21 21:02:44 +01:00
|
|
|
bsr eax, x
|
2008-10-17 11:57:36 +02:00
|
|
|
cmovz eax,edx
|
2007-01-21 21:02:44 +01:00
|
|
|
mov result, eax
|
|
|
|
|
2008-10-17 11:57:36 +02:00
|
|
|
//
|
|
|
|
pop edx
|
|
|
|
//
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
pop eax
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2008-10-17 11:57:36 +02:00
|
|
|
"push %%edx \n"
|
|
|
|
"andl $-1,%%edx \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
"bsrl %1, %0 \n"
|
2008-10-17 11:57:36 +02:00
|
|
|
"cmovz %%edx,%0 \n"
|
|
|
|
"pop %%edx \n"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-02-24 19:59:05 +01:00
|
|
|
: "=R" (result)
|
|
|
|
: "R" (x)
|
2007-01-21 21:02:44 +01:00
|
|
|
: "cc" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
/*!
|
|
|
|
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..31>
|
|
|
|
|
|
|
|
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] != 0
|
2007-01-29 18:58:18 +01:00
|
|
|
index = FindLeadingBitInWord( table[table_id] );
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
|
|
|
|
#ifdef TTMATH_PLATFORM32
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
/*!
|
|
|
|
this method sets a special bit in the 'value'
|
|
|
|
and returns the result
|
|
|
|
|
|
|
|
bit is from <0,31>
|
|
|
|
|
|
|
|
e.g.
|
|
|
|
SetBitInWord(0,0) = 1
|
|
|
|
SetBitInWord(0,2) = 4
|
|
|
|
SetBitInWord(10, 8) = 266
|
|
|
|
*/
|
|
|
|
static uint SetBitInWord(uint value, uint bit)
|
|
|
|
{
|
|
|
|
#ifndef __GNUC__
|
|
|
|
__asm
|
|
|
|
{
|
|
|
|
push ebx
|
|
|
|
push eax
|
|
|
|
mov eax, value
|
|
|
|
mov ebx, bit
|
|
|
|
bts eax, ebx
|
|
|
|
mov value, eax
|
|
|
|
pop eax
|
|
|
|
pop ebx
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
__asm__ __volatile__(
|
|
|
|
|
|
|
|
"btsl %%ebx,%%eax \n"
|
|
|
|
|
|
|
|
: "=a" (value)
|
|
|
|
: "0" (value), "b" (bit)
|
|
|
|
: "cc" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
setting the 'bit_index' bit
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
bit_index bigger or equal zero
|
|
|
|
*/
|
|
|
|
void SetBit(uint bit_index)
|
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
uint index = bit_index / TTMATH_BITS_PER_UINT;
|
2007-01-21 21:02:44 +01:00
|
|
|
if( index >= value_size )
|
|
|
|
return;
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
bit_index %= TTMATH_BITS_PER_UINT;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
table[index] = SetBitInWord(table[index], bit_index);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
Big::BitAnd(), Big::BitOr(), Big::BitXor()
added: to the parser: bitand(), bitor(), bitxor()
/band(), bor(), bxor()/
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@36 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-13 20:14:11 +02:00
|
|
|
/*!
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method performs a bitwise operation NOT
|
|
|
|
*/
|
|
|
|
void BitNot()
|
|
|
|
{
|
|
|
|
for(uint x=0 ; x<value_size ; ++x)
|
|
|
|
table[x] = ~table[x];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-23 23:35:55 +02:00
|
|
|
/*!
|
|
|
|
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
|
|
|
|
*/
|
2007-07-23 01:20:09 +02:00
|
|
|
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;
|
2007-04-23 23:35:55 +02:00
|
|
|
}
|
|
|
|
|
added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
Big::BitAnd(), Big::BitOr(), Big::BitXor()
added: to the parser: bitand(), bitor(), bitxor()
/band(), bor(), bxor()/
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@36 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-13 20:14:11 +02:00
|
|
|
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* Multiplication
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
public:
|
2007-01-21 21:02:44 +01:00
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
|
added: UInt::BitAnd(), UInt::BitOr(), UInt::BitXor(), UInt::BitNot(),
Big::BitAnd(), Big::BitOr(), Big::BitXor()
added: to the parser: bitand(), bitor(), bitxor()
/band(), bor(), bxor()/
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@36 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-04-13 20:14:11 +02:00
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
#ifdef TTMATH_PLATFORM32
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
|
|
|
multiplication: result2:result1 = a * b
|
|
|
|
result2 - higher word
|
|
|
|
result1 - lower word of the result
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
this method never returns a carry
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
it is an auxiliary method for version two of the multiplication algorithm
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
static void MulTwoWords(uint a, uint b, uint * result2, uint * result1)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
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
|
2008-10-17 11:57:36 +02:00
|
|
|
using gcc and options like -Ox
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
register uint result1_;
|
|
|
|
register 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__
|
|
|
|
|
2007-02-24 19:59:05 +01:00
|
|
|
__asm__ __volatile__(
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
"mull %%edx \n"
|
|
|
|
|
|
|
|
: "=a" (result1_), "=d" (result2_)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "0" (a), "1" (b)
|
2007-01-21 21:02:44 +01:00
|
|
|
: "cc" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
*result1 = result1_;
|
|
|
|
*result2 = result2_;
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
/*!
|
|
|
|
multiplication: this = this * ss2
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
it returns a carry if it has been
|
2007-01-22 21:25:45 +01:00
|
|
|
*/
|
|
|
|
uint MulInt(uint ss2)
|
|
|
|
{
|
|
|
|
uint r2,r1;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
UInt<value_size> u( *this );
|
|
|
|
SetZero();
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
for(uint x1=0 ; x1<value_size ; ++x1)
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
MulTwoWords(u.table[x1], ss2, &r2, &r1 );
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
|
|
|
|
if( x1 <= value_size - 2 )
|
|
|
|
{
|
2007-02-05 18:40:23 +01:00
|
|
|
if( AddTwoInts(r2,r1,x1) )
|
2007-01-22 21:25:45 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// last iteration:
|
|
|
|
// x1 = value_size - 1;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
if( r2 )
|
|
|
|
return 1;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
if( AddInt(r1, x1) )
|
2007-01-22 21:25:45 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-04-08 00:21:31 +02:00
|
|
|
/*!
|
|
|
|
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>
|
|
|
|
uint MulInt(uint ss2, UInt<result_size> & result)
|
|
|
|
{
|
|
|
|
uint r2,r1;
|
|
|
|
uint x1size=value_size;
|
|
|
|
uint x1start=0;
|
|
|
|
|
|
|
|
if( value_size >= result_size )
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
result.SetZero();
|
|
|
|
|
|
|
|
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 )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
/*!
|
2007-01-29 18:58:18 +01:00
|
|
|
the multiplication 'this' = 'this' * ss2
|
2007-01-22 21:25:45 +01:00
|
|
|
*/
|
|
|
|
uint Mul(const UInt<value_size> & ss2, uint algorithm = 2)
|
|
|
|
{
|
|
|
|
switch( algorithm )
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
return Mul1(ss2);
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
case 2:
|
2007-01-22 21:25:45 +01:00
|
|
|
default:
|
|
|
|
return Mul2(ss2);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
2007-01-22 21:25:45 +01:00
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
/*!
|
2007-01-29 18:58:18 +01:00
|
|
|
the multiplication 'result' = 'this' * ss2
|
2007-01-22 21:25:45 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
since the 'result' is twice bigger than 'this' and 'ss2'
|
|
|
|
this method never returns a carry
|
2007-01-22 21:25:45 +01:00
|
|
|
*/
|
|
|
|
void MulBig(const UInt<value_size> & ss2,
|
|
|
|
UInt<value_size*2> & result,
|
|
|
|
uint algorithm = 2)
|
|
|
|
{
|
|
|
|
switch( algorithm )
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
case 1:
|
|
|
|
return Mul1Big(ss2, result);
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
case 2:
|
2007-01-22 21:25:45 +01:00
|
|
|
default:
|
|
|
|
return Mul2Big(ss2, result);
|
|
|
|
}
|
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
|
|
|
|
/*!
|
|
|
|
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) )
|
|
|
|
return 1;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
if( ss1.Rcl(1) )
|
2007-01-22 21:25:45 +01:00
|
|
|
if( Add(ss2) )
|
|
|
|
return 1;
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
/*!
|
|
|
|
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)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
result.table[i] = table[i];
|
|
|
|
ss2.table[i] = ss2_.table[i];
|
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
// 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 );
|
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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;
|
|
|
|
|
|
|
|
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 )
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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)
|
|
|
|
{
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
uint r2,r1;
|
|
|
|
uint x1size=value_size, x2size=value_size;
|
|
|
|
uint x1start=0, x2start=0;
|
2007-01-22 21:25:45 +01:00
|
|
|
|
|
|
|
result.SetZero();
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
if( value_size > 2 )
|
|
|
|
{
|
|
|
|
// if the value_size is smaller than or equal to 2
|
|
|
|
// there is no sense to set x1size (and others) to another values
|
2007-01-22 21:25:45 +01:00
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
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 )
|
|
|
|
return;
|
2007-01-22 21:25:45 +01:00
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
for(x1start=0 ; x1start<x1size && table[x1start]==0 ; ++x1start);
|
|
|
|
for(x2start=0 ; x2start<x2size && ss2.table[x2start]==0 ; ++x2start);
|
|
|
|
}
|
2007-01-22 21:25:45 +01:00
|
|
|
|
|
|
|
for(uint x1=x1start ; x1<x1size ; ++x1)
|
|
|
|
{
|
|
|
|
for(uint x2=x2start ; x2<x2size ; ++x2)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
MulTwoWords(table[x1], ss2.table[x2], &r2, &r1);
|
2007-02-05 18:40:23 +01:00
|
|
|
result.AddTwoInts(r2,r1,x2+x1);
|
2007-01-29 18:58:18 +01:00
|
|
|
// here will never be a carry
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
}
|
2007-01-22 21:25:45 +01:00
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* Division
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
public:
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
#ifdef TTMATH_PLATFORM32
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
|
|
|
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
|
|
|
|
*
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
static void DivTwoWords(uint a, uint b, uint c, uint * r, uint * rest)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
register uint r_;
|
|
|
|
register uint rest_;
|
|
|
|
/*
|
|
|
|
these variables have similar meaning like those in
|
2007-01-29 18:58:18 +01:00
|
|
|
the multiplication algorithm MulTwoWords
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#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__ __volatile__(
|
|
|
|
|
|
|
|
"divl %%ecx \n"
|
|
|
|
|
|
|
|
: "=a" (r_), "=d" (rest_)
|
|
|
|
: "d" (a), "a" (b), "c" (c)
|
|
|
|
: "cc" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
*r = r_;
|
|
|
|
*rest = rest_;
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
division by one unsigned word
|
|
|
|
*/
|
|
|
|
uint DivInt(uint divisor, uint * remainder = 0)
|
|
|
|
{
|
|
|
|
if( divisor == 1 )
|
|
|
|
{
|
|
|
|
SetZero();
|
|
|
|
|
|
|
|
if( remainder )
|
|
|
|
*remainder = 0;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
UInt<value_size> dividend(*this);
|
|
|
|
SetZero();
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
sint i; // i must be with a sign
|
2007-01-21 21:02:44 +01:00
|
|
|
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)
|
2007-01-29 18:58:18 +01:00
|
|
|
DivTwoWords(r, dividend.table[i], divisor, &table[i], &r);
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
if( remainder )
|
|
|
|
*remainder = r;
|
|
|
|
|
|
|
|
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,
|
2007-01-29 18:58:18 +01:00
|
|
|
uint algorithm = 3)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
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();
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case 3: // 'this' is smaller than v
|
|
|
|
if( remainder )
|
|
|
|
*remainder = *this;
|
|
|
|
|
|
|
|
SetZero();
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case 2: // 'this' is zero
|
|
|
|
if( remainder )
|
|
|
|
remainder->SetZero();
|
|
|
|
|
|
|
|
SetZero();
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case 1: // v is zero
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
for(n = value_size-1 ; n!=0 && v.table[n]==0 ; --n);
|
|
|
|
|
|
|
|
if( n==0 && v.table[n]==0 )
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
for(m = value_size-1 ; 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's 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)
|
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
TTMATH_REFERENCE_ASSERT( divisor )
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
sint loop;
|
|
|
|
sint c;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
rest.SetZero();
|
2007-01-22 21:25:45 +01:00
|
|
|
loop = value_size * TTMATH_BITS_PER_UINT;
|
2007-01-21 21:02:44 +01:00
|
|
|
c = 0;
|
|
|
|
|
|
|
|
|
|
|
|
div_a:
|
2007-04-12 00:14:17 +02:00
|
|
|
c = Rcl(1, c);
|
2007-01-21 21:02:44 +01:00
|
|
|
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;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
c = Rcl(1, c);
|
2007-01-21 21:02:44 +01:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
div_c:
|
2007-04-12 00:14:17 +02:00
|
|
|
c = Rcl(1, c);
|
2007-01-21 21:02:44 +01:00
|
|
|
c = rest.Add(rest,c);
|
|
|
|
c = rest.Add(divisor);
|
|
|
|
|
|
|
|
if(c)
|
|
|
|
goto div_b;
|
|
|
|
|
|
|
|
|
|
|
|
div_d:
|
|
|
|
--loop;
|
|
|
|
if(loop)
|
|
|
|
goto div_c;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
c = Rcl(1, c);
|
2007-01-21 21:02:44 +01:00
|
|
|
c = rest.Add(divisor);
|
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
TTMATH_REFERENCE_ASSERT( divisor )
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
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 )
|
|
|
|
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) )
|
|
|
|
{
|
2007-04-12 00:14:17 +02:00
|
|
|
divisor_copy.Rcr(1);
|
2007-01-21 21:02:44 +01:00
|
|
|
--bits_diff;
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
Sub(divisor_copy, 0);
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
if( !FindLeadingBit(table_id, index) )
|
|
|
|
{
|
|
|
|
// zero is divided by something
|
|
|
|
|
|
|
|
SetZero();
|
|
|
|
|
|
|
|
if( remainder )
|
|
|
|
remainder->SetZero();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
divisor_index += divisor_table_id * TTMATH_BITS_PER_UINT;
|
|
|
|
index += table_id * TTMATH_BITS_PER_UINT;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( Div2_DivisorGreaterOrEqual( divisor, remainder,
|
|
|
|
table_id, index,
|
|
|
|
divisor_table_id, divisor_index) )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
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_table_id, uint divisor_index )
|
|
|
|
{
|
|
|
|
if( divisor_index > index )
|
|
|
|
{
|
|
|
|
// divisor is greater than this
|
|
|
|
|
|
|
|
if( remainder )
|
|
|
|
*remainder = *this;
|
|
|
|
|
|
|
|
SetZero();
|
|
|
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if( table[i] == divisor.table[i] )
|
|
|
|
{
|
|
|
|
// divisor is equal 'this'
|
|
|
|
|
|
|
|
if( remainder )
|
|
|
|
remainder->SetZero();
|
|
|
|
|
|
|
|
SetOne();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/*!
|
|
|
|
the third division algorithm
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
this algorithm is described in the following book:
|
2007-01-21 21:02:44 +01:00
|
|
|
"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)
|
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
TTMATH_REFERENCE_ASSERT( v )
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
|
|
void Div3_Division(UInt<value_size> v, UInt<value_size> * remainder, uint m, uint n)
|
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
TTMATH_ASSERT( n>=2 )
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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)
|
|
|
|
{
|
|
|
|
uint c = 0;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
// !!!!!!!!! change
|
2007-01-22 21:25:45 +01:00
|
|
|
for( d = 0 ; (v.table[n-1] & TTMATH_UINT_HIGHEST_BIT) == 0 ; ++d )
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
// we can move the bits only to the 'n-1' index but at the moment
|
|
|
|
// we don't have such method
|
|
|
|
// maybe it's time to write it now?
|
2007-04-12 00:14:17 +02:00
|
|
|
v.Rcl(1, 0);
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
c <<= 1;
|
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
if( Rcl(1, 0) )
|
2007-01-21 21:02:44 +01:00
|
|
|
c += 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
uint Div3_Calculate(uint u2, uint u1, uint u0, uint v1, uint v0)
|
|
|
|
{
|
|
|
|
UInt<2> u_temp;
|
|
|
|
uint rp;
|
|
|
|
bool next_test;
|
|
|
|
|
|
|
|
u_temp.table[1] = u2;
|
|
|
|
u_temp.table[0] = u1;
|
|
|
|
u_temp.DivInt(v1, &rp);
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
TTMATH_ASSERT( u_temp.table[1]==0 || u_temp.table[1]==1 )
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
bool decrease = false;
|
|
|
|
|
|
|
|
if( u_temp.table[1] == 1 )
|
|
|
|
decrease = true;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
UInt<2> temp1, temp2;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
UInt<2>::MulTwoWords(u_temp.table[0], v0, temp1.table+1, temp1.table);
|
2007-01-21 21:02:44 +01:00
|
|
|
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 );
|
|
|
|
|
|
|
|
|
|
|
|
return u_temp.table[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Div3_MultiplySubtract( UInt<value_size+1> & uu,
|
|
|
|
const UInt<value_size+1> & vv, uint & qp)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
this method sets n first bits to value zero
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
For example:
|
|
|
|
let n=2 then if there's a value 111 (bin) there'll be '100' (bin)
|
|
|
|
*/
|
|
|
|
void ClearFirstBits(uint n)
|
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
if( n >= value_size*TTMATH_BITS_PER_UINT )
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
SetZero();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint * p = table;
|
|
|
|
|
|
|
|
// first we're clearing the whole words
|
2007-01-22 21:25:45 +01:00
|
|
|
while( n >= TTMATH_BITS_PER_UINT )
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
*p++ = 0;
|
2007-01-22 21:25:45 +01:00
|
|
|
n -= TTMATH_BITS_PER_UINT;
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if( n == 0 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// and then we're clearing one word which has left
|
|
|
|
// mask -- all bits are set to one
|
2007-01-22 21:25:45 +01:00
|
|
|
uint mask = TTMATH_UINT_MAX_VALUE;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
mask = mask << n;
|
|
|
|
|
|
|
|
(*p) &= mask;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
this method returns true if the highest bit of the value is set
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
bool IsTheHighestBitSet() const
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
return (table[value_size-1] & TTMATH_UINT_HIGHEST_BIT) != 0;
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
this method returns true if the lowest bit of the value is set
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
bool IsTheLowestBitSet() const
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
return (*table & 1) != 0;
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2008-06-18 02:33:05 +02:00
|
|
|
this method returns true if the value is equal zero
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
bool IsZero() const
|
|
|
|
{
|
|
|
|
for(uint i=0 ; i<value_size ; ++i)
|
|
|
|
if(table[i] != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
*
|
2008-10-17 11:57:36 +02:00
|
|
|
* conversion method
|
2007-01-21 21:02:44 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this static method converts one character into its value
|
|
|
|
|
|
|
|
for example:
|
|
|
|
1 -> 1
|
|
|
|
8 -> 8
|
|
|
|
A -> 10
|
|
|
|
f -> 15
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
this method don't check whether c is correct or not
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
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
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
static sint CharToDigit(uint c, uint base)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
return sint(c);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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';
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2007-01-29 18:58:18 +01:00
|
|
|
this method converts an UInt<another_size> type to this class
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
this operation has mainly sense if the value from p is
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
equal or smaller than that one which is returned from UInt<value_size>::SetMax()
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
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];
|
|
|
|
|
|
|
|
|
2007-01-22 21:25:45 +01:00
|
|
|
if( value_size > argument_size )
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-22 21:25:45 +01:00
|
|
|
// 'this' is longer than 'p'
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
for( ; i<value_size ; ++i)
|
|
|
|
table[i] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for( ; i<argument_size ; ++i)
|
|
|
|
if( p.table[i] != 0 )
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
/*!
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
2007-02-27 21:18:33 +01:00
|
|
|
this operator converts an UInt<another_size> type to this class
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
it doesn't return a carry
|
|
|
|
*/
|
|
|
|
template<uint argument_size>
|
|
|
|
UInt<value_size> & operator=(const UInt<argument_size> & p)
|
|
|
|
{
|
|
|
|
FromUInt(p);
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2007-01-29 18:58:18 +01:00
|
|
|
the assignment operator
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
UInt<value_size> & operator=(const UInt<value_size> & p)
|
|
|
|
{
|
|
|
|
FromUInt(p);
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
this method converts the uint type to this class
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
UInt<value_size> & operator=(uint i)
|
|
|
|
{
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
FromUInt(i);
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
a constructor for converting the uint to this class
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
UInt(uint i)
|
|
|
|
{
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
FromUInt(i);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
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;
|
|
|
|
|
|
|
|
this constant 10 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));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
a constructor for converting a string to this class (with the base=10)
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
UInt(const char * s)
|
|
|
|
{
|
|
|
|
FromString(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
a constructor for converting a string to this class (with the base=10)
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
UInt(const std::string & s)
|
|
|
|
{
|
|
|
|
FromString( s.c_str() );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2007-02-05 18:40:23 +01:00
|
|
|
a default constructor
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
we don't clear table etc.
|
|
|
|
*/
|
|
|
|
UInt()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2007-02-05 18:40:23 +01:00
|
|
|
a copy constructor
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
UInt(const UInt<value_size> & u)
|
|
|
|
{
|
|
|
|
FromUInt(u);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-27 21:18:33 +01:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
2007-01-29 18:58:18 +01:00
|
|
|
a template for producting constructors for copying from another types
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-27 21:18:33 +01:00
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
2007-02-05 18:40:23 +01:00
|
|
|
a destructor
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
~UInt()
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method returns the lowest value from table
|
|
|
|
|
|
|
|
we must be sure when we using this method whether the value
|
2007-01-29 18:58:18 +01:00
|
|
|
will hold in an uint type or not (the rest value from the table must be zero)
|
2007-01-21 21:02:44 +01:00
|
|
|
*/
|
|
|
|
uint ToUInt() const
|
|
|
|
{
|
|
|
|
return table[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method converts the value to a string with a base equal 'b'
|
|
|
|
*/
|
|
|
|
void ToString(std::string & 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 = DigitToChar( rem );
|
|
|
|
result.insert(result.begin(), character);
|
|
|
|
}
|
|
|
|
while( !temp.IsZero() );
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
this method's ommiting any white characters from the string
|
|
|
|
*/
|
|
|
|
static void SkipWhiteCharacters(const char * & c)
|
|
|
|
{
|
|
|
|
while( (*c==' ' ) || (*c=='\t') || (*c==13 ) || (*c=='\n') )
|
|
|
|
++c;
|
|
|
|
}
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
|
|
|
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
|
|
|
|
*/
|
2008-10-21 19:42:41 +02:00
|
|
|
uint FromString(const char * s, uint b = 10, const char ** after_source = 0)
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
|
|
|
UInt<value_size> base( b );
|
|
|
|
UInt<value_size> temp;
|
2007-01-29 18:58:18 +01:00
|
|
|
sint z;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
SetZero();
|
|
|
|
temp.SetZero();
|
|
|
|
SkipWhiteCharacters(s);
|
|
|
|
|
2008-10-21 19:42:41 +02:00
|
|
|
if( after_source )
|
|
|
|
*after_source = s;
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
if( b<2 || b>16 )
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
for( ; (z=CharToDigit(*s, b)) != -1 ; ++s)
|
|
|
|
{
|
|
|
|
temp.table[0] = z;
|
|
|
|
|
2008-10-21 19:42:41 +02:00
|
|
|
if( Mul(base) || Add(temp) ) // first is called Mul() and next Add()
|
|
|
|
{
|
|
|
|
if( after_source )
|
|
|
|
*after_source = s;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
return 1;
|
2008-10-21 19:42:41 +02:00
|
|
|
}
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
2008-10-21 19:42:41 +02:00
|
|
|
if( after_source )
|
|
|
|
*after_source = s;
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method converts a string into its value
|
|
|
|
|
|
|
|
(it returns carry=1 if the value will be too big or an incorrect base 'b' is given)
|
|
|
|
*/
|
|
|
|
uint FromString(const std::string & s, uint b = 10)
|
|
|
|
{
|
|
|
|
return FromString( s.c_str(), 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 std::string & s)
|
|
|
|
{
|
|
|
|
FromString( s.c_str() );
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* methods for comparing
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
/*!
|
|
|
|
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)
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
bool CmpSmaller(const UInt<value_size> & l, sint index = -1) const
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
sint i;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
if( index==-1 || index>=sint(value_size) )
|
2007-01-21 21:02:44 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
/*!
|
|
|
|
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)
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
bool CmpBigger(const UInt<value_size> & l, sint index = -1) const
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
sint i;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
if( index==-1 || index>=sint(value_size) )
|
2007-01-21 21:02:44 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
/*!
|
|
|
|
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)
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
bool CmpEqual(const UInt<value_size> & l, sint index = -1) const
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
sint i;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
if( index==-1 || index>=sint(value_size) )
|
2007-01-21 21:02:44 +01:00
|
|
|
i = value_size - 1;
|
|
|
|
else
|
|
|
|
i = index;
|
|
|
|
|
|
|
|
|
|
|
|
for( ; i>=0 ; --i)
|
|
|
|
if( table[i] != l.table[i] )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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)
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
bool CmpSmallerEqual(const UInt<value_size> & l, sint index=-1) const
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
sint i;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
if( index==-1 || index>=sint(value_size) )
|
2007-01-21 21:02:44 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
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)
|
|
|
|
*/
|
2007-01-29 18:58:18 +01:00
|
|
|
bool CmpBiggerEqual(const UInt<value_size> & l, sint index=-1) const
|
2007-01-21 21:02:44 +01:00
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
sint i;
|
2007-01-21 21:02:44 +01:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
if( index==-1 || index>=sint(value_size) )
|
2007-01-21 21:02:44 +01:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
/*
|
|
|
|
operators for comparising
|
|
|
|
*/
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
bool operator<(const UInt<value_size> & l) const
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
return CmpSmaller(l);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool operator>(const UInt<value_size> & l) const
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
return CmpBigger(l);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool operator==(const UInt<value_size> & l) const
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
return CmpEqual(l);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool operator!=(const UInt<value_size> & l) const
|
|
|
|
{
|
|
|
|
return !operator==(l);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool operator<=(const UInt<value_size> & l) const
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
return CmpSmallerEqual(l);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool operator>=(const UInt<value_size> & l) const
|
|
|
|
{
|
2007-01-29 18:58:18 +01:00
|
|
|
return CmpBiggerEqual(l);
|
2007-01-21 21:02:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* 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;
|
|
|
|
}
|
|
|
|
|
2008-06-18 02:33:05 +02:00
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
/*!
|
|
|
|
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--()
|
|
|
|
{
|
2007-02-05 18:40:23 +01:00
|
|
|
SubOne();
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
UInt<value_size> operator--(int)
|
|
|
|
{
|
|
|
|
UInt<value_size> temp( *this );
|
|
|
|
|
|
|
|
SubOne();
|
|
|
|
|
|
|
|
return temp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* input/output operators for standard streams
|
2007-01-29 18:58:18 +01:00
|
|
|
*
|
|
|
|
* (they are very simple, in the future they should be changed)
|
2007-01-21 21:02:44 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
friend std::ostream & operator<<(std::ostream & s, const UInt<value_size> & l)
|
|
|
|
{
|
|
|
|
std::string ss;
|
|
|
|
|
|
|
|
l.ToString(ss);
|
|
|
|
s << ss;
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
friend std::istream & operator>>(std::istream & s, UInt<value_size> & l)
|
|
|
|
{
|
|
|
|
std::string ss;
|
|
|
|
|
|
|
|
// char for operator>>
|
|
|
|
unsigned char z;
|
|
|
|
|
|
|
|
// operator>> omits white characters if they're set for ommiting
|
|
|
|
s >> z;
|
|
|
|
|
|
|
|
// we're reading only digits (base=10)
|
|
|
|
while( s.good() && CharToDigit(z, 10)>=0 )
|
|
|
|
{
|
|
|
|
ss += z;
|
|
|
|
z = s.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
// we're leaving the last readed character
|
|
|
|
// (it's not belonging to the value)
|
|
|
|
s.unget();
|
|
|
|
|
|
|
|
l.FromString(ss);
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
#ifdef TTMATH_PLATFORM64
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
private:
|
2008-10-31 00:38:24 +01:00
|
|
|
uint Rcl2_one(uint c);
|
|
|
|
uint Rcr2_one(uint c);
|
2007-04-12 00:14:17 +02:00
|
|
|
uint Rcl2(uint bits, uint c);
|
|
|
|
uint Rcr2(uint bits, uint c);
|
|
|
|
|
|
|
|
public:
|
added: DegToDeg(deg, min, sec), DegToRad(deg), DegToRad(deg, min, sec),
RadToDeg(rad), Ceil(x), Floor(x), Sqrt(x), Sinh(x), Cosh(x),
Tanh(x) /Tgh(x)/, Coth(x) /Ctgh(x)/
changed: class Objects in ttmathobjects.h has been completely rewritten, we can
change the names of user-defined variables or functions, and the names are
case-sensitive now
added: class History which is used in functions which take a lot of time
during calculating e.g. Factorial(x)
added: Tg(x) a wrapper for Tan(x)
changed: CTan(x) is Cot(x) now
added: Ctg(x) a wrapper for Cot(x)
added: ATg(x) a wrapper for ATan(x)
changed: ACTan(x) is ACot(x) now
added: ACtg(x) a wrapper for ACot(x)
added: UInt::PrintTable() (for debugging etc.)
changed: the methods Big::SetPi() Big::SetE() and Big::SetLn2() have been
rewritten, now they have 128 32bit words (it's about 1232 valid
decimal digits)
fixed: previous values from Big::SetPi() Big::SetE() and Big::SetLn2() were
not too much accurate (last 2-3 words were wrong)
added: Big::SetLn10() (128 32bit words as well)
added: macro: TTMATH_BUILTIN_VARIABLES_SIZE which is equal 128u on 32bit
platforms and 64ul on 64bit platforms (128/2=64)
added: macros: TTMATH_PLATFORM32 and TTMATH_PLATFORM64
changed: a small optimisation in UInt::Mul2Big()
added: at the end of ttmath.h: #include "ttmathparser.h"
this is for convenience for a programmer, he can only use #include
with ttmath.h even if he uses the parser
added: to samples: big.cpp, parser.cpp
fixed: constructor Big::Big(uint) - it was wrong because
it was using the method Big::FromInt(sint) which could produce wrong
values (if the 'uint' couldn't correctly be casted into the 'sint')
added: Big::FromUInt(uint)
changed: Big::FromInt(sint), Big::SetOne(), renamed Big::SetDotOne() into
Big::Set05()
(they are a little faster now)
added: Big::operator=(uint)
changed: in 64bit mode: constructor: Big::Big(int)
added: in 64bit mode: constructor: Big::Big(unsigned int),
operators: Big::operator=(signed int) and Big::operator=(unsigned int)
(these operators and the constructor take a 32bit value)
deleted: the word 'virtual' from destructors: UInt, Int, Big
(types in this library are not projected to be base-classes for
another ones derived from them)
changed: UInt::operator=(uint), UInt::UInt(uint), Int::operator=(sint), Int::Int(sint)
added: UInt::FromUInt(uint), UInt::operator=(sint), UInt::UInt(sint),
Int::FromInt(sint), Int::operator=(uint), Int::Int(uint),
Int::operator==(const Int<>&), Int::operator!=(const Int<>&)
added: in 64bit mode: UInt::operator=(unsigned int), UInt::UInt(unsigned int),
UInt::operator=(signed int), UInt::UInt(signed int)
(these operators and the constructors take a 32bit value)
added: in 64bit mode: Int::operator=(signed int), Int::Int(signed int),
Int::operator=(unsigned int), Int::Int(unsigned int)
(these operators and the constructors take a 32bit value)
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@25 e52654a7-88a9-db11-a3e9-0013d4bc506e
2007-03-29 00:27:57 +02:00
|
|
|
// these methods are for 64bit processors and are defined in 'ttmathuint64.h'
|
|
|
|
UInt<value_size> & operator=(unsigned int i);
|
|
|
|
UInt(unsigned int i);
|
|
|
|
UInt<value_size> & operator=(signed int i);
|
|
|
|
UInt(signed int i);
|
2007-02-24 19:59:05 +01:00
|
|
|
void SetFromTable(const unsigned int * temp_table, uint temp_table_len);
|
2007-01-29 18:58:18 +01:00
|
|
|
uint Add(const UInt<value_size> & ss2, uint c=0);
|
|
|
|
uint AddInt(uint value, uint index = 0);
|
2007-02-05 18:40:23 +01:00
|
|
|
uint AddTwoInts(uint x2, uint x1, uint index);
|
2007-01-29 18:58:18 +01:00
|
|
|
uint Sub(const UInt<value_size> & ss2, uint c=0);
|
|
|
|
uint SubInt(uint value, uint index = 0);
|
|
|
|
static sint FindLeadingBitInWord(uint x);
|
|
|
|
static uint SetBitInWord(uint value, uint bit);
|
|
|
|
static void MulTwoWords(uint a, uint b, uint * result2, uint * result1);
|
|
|
|
static void DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2007-01-21 21:02:44 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
} //namespace
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#include "ttmathuint64.h"
|
2007-01-21 21:02:44 +01:00
|
|
|
|
|
|
|
|
|
|
|
#endif
|