2007-01-29 18:58:18 +01:00
|
|
|
/*
|
2009-03-12 21:54:46 +01:00
|
|
|
* This file is a part of TTMath Bignum Library
|
2007-01-29 18:58:18 +01:00
|
|
|
* and is distributed under the (new) BSD licence.
|
2009-07-02 03:04:25 +02:00
|
|
|
* Author: Tomasz Sowa <t.sowa@ttmath.org>
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2009-03-11 20:05:13 +01:00
|
|
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
2007-01-29 18:58:18 +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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2009-05-04 22:51:12 +02:00
|
|
|
#ifndef headerfilettmathuint_x86_64
|
|
|
|
#define headerfilettmathuint_x86_64
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef TTMATH_NOASM
|
|
|
|
#ifdef TTMATH_PLATFORM64
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
/*!
|
2009-05-04 22:51:12 +02:00
|
|
|
\file ttmathuint_x86_64.h
|
|
|
|
\brief template class UInt<uint> with assembler code for 64bit x86_64 processors
|
|
|
|
|
|
|
|
this file is included at the end of ttmathuint.h
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
#include <intrin.h>
|
|
|
|
#endif
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
namespace ttmath
|
|
|
|
{
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
2009-09-12 01:55:44 +02:00
|
|
|
uint __fastcall ttmath_adc_x64(uint* p1, const uint* p2, uint nSize, uint c);
|
|
|
|
uint __fastcall ttmath_addindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
|
|
|
|
uint __fastcall ttmath_addindexed2_x64(uint* p1, uint nSize, uint nPos, uint nValue1, uint nValue2);
|
|
|
|
uint __fastcall ttmath_addvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
|
|
|
|
uint __fastcall ttmath_sbb_x64(uint* p1, const uint* p2, uint nSize, uint c);
|
|
|
|
uint __fastcall ttmath_subindexed_x64(uint* p1, uint nSize, uint nPos, uint nValue);
|
|
|
|
uint __fastcall ttmath_subvector_x64(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result);
|
|
|
|
uint __fastcall ttmath_rcl_x64(uint* p1, uint nSize, uint nLowestBit);
|
|
|
|
uint __fastcall ttmath_rcr_x64(uint* p1, uint nSize, uint nLowestBit);
|
|
|
|
uint __fastcall ttmath_div_x64(uint* pnValHi, uint* pnValLo, uint nDiv);
|
|
|
|
uint __fastcall ttmath_rcl2_x64(uint* p1, uint nSize, uint nBits, uint c);
|
|
|
|
uint __fastcall ttmath_rcr2_x64(uint* p1, uint nSize, uint nBits, uint c);
|
2009-09-07 04:03:00 +02:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* basic mathematic functions
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2007-02-24 19:59:05 +01:00
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
/*!
|
|
|
|
this method adding ss2 to the this and adding carry if it's defined
|
|
|
|
(this = this + ss2 + c)
|
|
|
|
|
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 created only on a 64bit platform***
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
c must be zero or one (might be a bigger value than 1)
|
|
|
|
function returns carry (1) (if it was)
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
uint UInt<value_size>::Add(const UInt<value_size> & ss2, uint c)
|
|
|
|
{
|
2009-05-05 09:20:10 +02:00
|
|
|
uint b = value_size;
|
|
|
|
uint * p1 = table;
|
2009-05-05 09:47:10 +02:00
|
|
|
const uint * p2 = ss2.table;
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
|
|
|
// this algorithm doesn't require it
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_adc_x64(p1,p2,b,c);
|
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
|
|
|
#endif
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy, dummy2;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
/*
|
|
|
|
this part should be compiled with gcc
|
|
|
|
*/
|
|
|
|
__asm__ __volatile__(
|
2009-05-05 09:20:10 +02:00
|
|
|
|
|
|
|
"xorq %%rdx, %%rdx \n"
|
2009-05-17 02:04:42 +02:00
|
|
|
"negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
2008-10-22 20:56:04 +02:00
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"1: \n"
|
2009-05-05 09:20:10 +02:00
|
|
|
"movq (%%rsi,%%rdx,8), %%rax \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"adcq %%rax, (%%rbx,%%rdx,8) \n"
|
|
|
|
|
|
|
|
"incq %%rdx \n"
|
|
|
|
"decq %%rcx \n"
|
|
|
|
"jnz 1b \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
"adcq %%rcx, %%rcx \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
: "=c" (c), "=a" (dummy), "=d" (dummy2)
|
2009-05-17 02:04:42 +02:00
|
|
|
: "0" (b), "1" (c), "b" (p1), "S" (p2)
|
2009-05-05 09:20:10 +02:00
|
|
|
: "cc", "memory" );
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::Add", c)
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method adds one word (at a specific position)
|
|
|
|
and returns a carry (if it was)
|
|
|
|
|
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 created only on a 64bit platform***
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2009-05-08 20:14:00 +02:00
|
|
|
of course if there was a carry from table[2] it would be returned
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
uint UInt<value_size>::AddInt(uint value, uint index)
|
|
|
|
{
|
2009-05-05 09:20:10 +02:00
|
|
|
uint b = value_size;
|
|
|
|
uint * p1 = table;
|
|
|
|
uint c;
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
TTMATH_ASSERT( index < value_size )
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
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
|
|
|
#endif
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_addindexed_x64(p1,b,index,value);
|
2009-09-07 04:03:00 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy, dummy2;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
__asm__ __volatile__(
|
2008-10-25 22:05:51 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
"subq %%rdx, %%rcx \n"
|
|
|
|
|
|
|
|
"1: \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"addq %%rax, (%%rbx,%%rdx,8) \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
"jnc 2f \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
|
|
|
|
"movq $1, %%rax \n"
|
|
|
|
"incq %%rdx \n"
|
|
|
|
"decq %%rcx \n"
|
|
|
|
"jnz 1b \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
"2: \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"setc %%al \n"
|
|
|
|
"movzx %%al, %%rdx \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
: "=d" (c), "=a" (dummy), "=c" (dummy2)
|
|
|
|
: "0" (index), "1" (value), "2" (b), "b" (p1)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::AddInt", c)
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method adds only two unsigned words to the existing value
|
|
|
|
and these words begin on the 'index' position
|
|
|
|
(it's used in the multiplication algorithm 2)
|
|
|
|
|
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 created only on a 64bit platform***
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
index should be equal or smaller than value_size-2 (index <= value_size-2)
|
|
|
|
x1 - lower word, x2 - higher word
|
|
|
|
|
|
|
|
for example if we've got value_size equal 4 and:
|
|
|
|
table[0] = 3
|
|
|
|
table[1] = 4
|
|
|
|
table[2] = 5
|
|
|
|
table[3] = 6
|
|
|
|
then let
|
|
|
|
x1 = 10
|
|
|
|
x2 = 20
|
|
|
|
and
|
|
|
|
index = 1
|
|
|
|
|
|
|
|
the result of this method will be:
|
|
|
|
table[0] = 3
|
|
|
|
table[1] = 4 + x1 = 14
|
|
|
|
table[2] = 5 + x2 = 25
|
|
|
|
table[3] = 6
|
|
|
|
|
|
|
|
and no carry at the end of table[3]
|
|
|
|
|
|
|
|
(of course if there was a carry in table[2](5+20) then
|
|
|
|
this carry would be passed to the table[3] etc.)
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
2007-02-05 18:40:23 +01:00
|
|
|
uint UInt<value_size>::AddTwoInts(uint x2, uint x1, uint index)
|
2007-01-29 18:58:18 +01:00
|
|
|
{
|
2009-05-05 09:20:10 +02:00
|
|
|
uint b = value_size;
|
|
|
|
uint * p1 = table;
|
|
|
|
uint c;
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
TTMATH_ASSERT( index < value_size - 1 )
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
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
|
|
|
#endif
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_addindexed2_x64(p1,b,index,x1,x2);
|
2009-09-07 04:03:00 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy, dummy2;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
__asm__ __volatile__(
|
|
|
|
|
|
|
|
"subq %%rdx, %%rcx \n"
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"addq %%rsi, (%%rbx,%%rdx,8) \n"
|
|
|
|
"incq %%rdx \n"
|
|
|
|
"decq %%rcx \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
"1: \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"adcq %%rax, (%%rbx,%%rdx,8) \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
"jnc 2f \n"
|
|
|
|
|
2008-10-25 22:05:51 +02:00
|
|
|
"mov $0, %%rax \n"
|
|
|
|
"incq %%rdx \n"
|
|
|
|
"decq %%rcx \n"
|
|
|
|
"jnz 1b \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
"2: \n"
|
2008-10-25 22:05:51 +02:00
|
|
|
"setc %%al \n"
|
|
|
|
"movzx %%al, %%rax \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
: "=a" (c), "=c" (dummy), "=d" (dummy2)
|
2009-05-17 02:04:42 +02:00
|
|
|
: "0" (x2), "1" (b), "2" (index), "b" (p1), "S" (x1)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::AddTwoInts", c)
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this static method addes one vector to the other
|
|
|
|
'ss1' is larger in size or equal to 'ss2'
|
|
|
|
|
|
|
|
ss1 points to the first (larger) vector
|
|
|
|
ss2 points to the second vector
|
|
|
|
ss1_size - size of the ss1 (and size of the result too)
|
|
|
|
ss2_size - size of the ss2
|
|
|
|
result - is the result vector (which has size the same as ss1: ss1_size)
|
|
|
|
|
|
|
|
Example: ss1_size is 5, ss2_size is 3
|
|
|
|
ss1: ss2: result (output):
|
|
|
|
5 1 5+1
|
|
|
|
4 3 4+3
|
|
|
|
2 7 2+7
|
|
|
|
6 6
|
|
|
|
9 9
|
|
|
|
of course the carry is propagated and will be returned from the last item
|
|
|
|
(this method is used by the Karatsuba multiplication algorithm)
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
uint UInt<value_size>::AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
|
|
|
{
|
|
|
|
TTMATH_ASSERT( ss1_size >= ss2_size )
|
|
|
|
|
|
|
|
uint c;
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_addvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy1, dummy2, dummy3;
|
2009-09-12 01:55:44 +02:00
|
|
|
uint rest = ss1_size - ss2_size;
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
// this part should be compiled with gcc
|
|
|
|
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
__asm__ __volatile__(
|
|
|
|
"mov %%rdx, %%r8 \n"
|
|
|
|
"xor %%rdx, %%rdx \n" // rdx = 0, cf = 0
|
|
|
|
"1: \n"
|
|
|
|
"mov (%%rsi,%%rdx,8), %%rax \n"
|
|
|
|
"adc (%%rbx,%%rdx,8), %%rax \n"
|
|
|
|
"mov %%rax, (%%rdi,%%rdx,8) \n"
|
|
|
|
|
|
|
|
"inc %%rdx \n"
|
|
|
|
"dec %%rcx \n"
|
|
|
|
"jnz 1b \n"
|
|
|
|
|
|
|
|
"adc %%rcx, %%rcx \n" // rcx has the cf state
|
|
|
|
|
|
|
|
"or %%r8, %%r8 \n"
|
|
|
|
"jz 3f \n"
|
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
"xor %%rbx, %%rbx \n" // ebx = 0
|
|
|
|
"neg %%rcx \n" // setting cf from rcx
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
"mov %%r8, %%rcx \n" // rcx=rest and is != 0
|
|
|
|
"2: \n"
|
|
|
|
"mov (%%rsi, %%rdx, 8), %%rax \n"
|
|
|
|
"adc %%rbx, %%rax \n"
|
|
|
|
"mov %%rax, (%%rdi, %%rdx, 8) \n"
|
|
|
|
|
|
|
|
"inc %%rdx \n"
|
|
|
|
"dec %%rcx \n"
|
|
|
|
"jnz 2b \n"
|
|
|
|
|
|
|
|
"adc %%rcx, %%rcx \n"
|
|
|
|
"3: \n"
|
|
|
|
|
|
|
|
: "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3)
|
|
|
|
: "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result)
|
|
|
|
: "%r8", "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_VECTOR_LOGC("UInt::AddVector", c, result, ss1_size)
|
2009-05-01 16:53:21 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method's subtracting ss2 from the 'this' and subtracting
|
|
|
|
carry if it has been defined
|
|
|
|
(this = this - ss2 - c)
|
|
|
|
|
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 created only on a 64bit platform***
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
c must be zero or one (might be a bigger value than 1)
|
|
|
|
function returns carry (1) (if it was)
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
uint UInt<value_size>::Sub(const UInt<value_size> & ss2, uint c)
|
|
|
|
{
|
2009-05-05 09:20:10 +02:00
|
|
|
uint b = value_size;
|
|
|
|
uint * p1 = table;
|
|
|
|
const uint * p2 = ss2.table;
|
2009-05-17 02:04:42 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
|
|
|
// this algorithm doesn't require it
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_sbb_x64(p1,p2,b,c);
|
2009-09-07 04:03:00 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy, dummy2;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
__asm__ __volatile__(
|
2009-05-05 09:20:10 +02:00
|
|
|
|
|
|
|
"xorq %%rdx, %%rdx \n"
|
2009-05-17 02:04:42 +02:00
|
|
|
"negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"1: \n"
|
2009-05-05 09:20:10 +02:00
|
|
|
"movq (%%rsi,%%rdx,8), %%rax \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"sbbq %%rax, (%%rbx,%%rdx,8) \n"
|
|
|
|
|
|
|
|
"incq %%rdx \n"
|
|
|
|
"decq %%rcx \n"
|
|
|
|
"jnz 1b \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
"adcq %%rcx, %%rcx \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
: "=c" (c), "=a" (dummy), "=d" (dummy2)
|
2009-05-17 02:04:42 +02:00
|
|
|
: "0" (b), "1" (c), "b" (p1), "S" (p2)
|
2009-05-05 09:20:10 +02:00
|
|
|
: "cc", "memory" );
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::Sub", c)
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-09-12 01:55:44 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
/*!
|
|
|
|
this method subtracts one word (at a specific position)
|
|
|
|
and returns a carry (if it was)
|
|
|
|
|
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 created only on a 64bit platform***
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
2009-05-08 20:14:00 +02:00
|
|
|
of course if there was a carry from table[2] it would be returned
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
uint UInt<value_size>::SubInt(uint value, uint index)
|
|
|
|
{
|
2009-05-05 09:20:10 +02:00
|
|
|
uint b = value_size;
|
|
|
|
uint * p1 = table;
|
|
|
|
uint c;
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
TTMATH_ASSERT( index < value_size )
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
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
|
|
|
#endif
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_subindexed_x64(p1,b,index,value);
|
2009-09-07 04:03:00 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
2009-09-07 04:03:00 +02:00
|
|
|
uint dummy, dummy2;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
__asm__ __volatile__(
|
|
|
|
|
|
|
|
"subq %%rdx, %%rcx \n"
|
|
|
|
|
|
|
|
"1: \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"subq %%rax, (%%rbx,%%rdx,8) \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
"jnc 2f \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
|
|
|
|
"movq $1, %%rax \n"
|
|
|
|
"incq %%rdx \n"
|
|
|
|
"decq %%rcx \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, %%rdx \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
: "=d" (c), "=a" (dummy), "=c" (dummy2)
|
|
|
|
: "0" (index), "1" (value), "2" (b), "b" (p1)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::SubInt", c)
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this static method subtractes one vector from the other
|
|
|
|
'ss1' is larger in size or equal to 'ss2'
|
|
|
|
|
|
|
|
ss1 points to the first (larger) vector
|
|
|
|
ss2 points to the second vector
|
|
|
|
ss1_size - size of the ss1 (and size of the result too)
|
|
|
|
ss2_size - size of the ss2
|
|
|
|
result - is the result vector (which has size the same as ss1: ss1_size)
|
|
|
|
|
|
|
|
Example: ss1_size is 5, ss2_size is 3
|
|
|
|
ss1: ss2: result (output):
|
|
|
|
5 1 5-1
|
|
|
|
4 3 4-3
|
|
|
|
2 7 2-7
|
|
|
|
6 6-1 (the borrow from previous item)
|
|
|
|
9 9
|
|
|
|
return (carry): 0
|
|
|
|
of course the carry (borrow) is propagated and will be returned from the last item
|
|
|
|
(this method is used by the Karatsuba multiplication algorithm)
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
uint UInt<value_size>::SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
|
|
|
|
{
|
|
|
|
TTMATH_ASSERT( ss1_size >= ss2_size )
|
|
|
|
|
|
|
|
uint c;
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_subvector_x64(ss1, ss2, ss1_size, ss2_size, result);
|
2009-09-07 04:03:00 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
#ifdef __GNUC__
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
// the asm code is nearly the same as in AddVector
|
|
|
|
// only two instructions 'adc' are changed to 'sbb'
|
|
|
|
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
uint dummy1, dummy2, dummy3;
|
2009-09-12 01:55:44 +02:00
|
|
|
uint rest = ss1_size - ss2_size;
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
|
|
|
|
__asm__ __volatile__(
|
|
|
|
"mov %%rdx, %%r8 \n"
|
|
|
|
"xor %%rdx, %%rdx \n" // rdx = 0, cf = 0
|
|
|
|
"1: \n"
|
|
|
|
"mov (%%rsi,%%rdx,8), %%rax \n"
|
|
|
|
"sbb (%%rbx,%%rdx,8), %%rax \n"
|
|
|
|
"mov %%rax, (%%rdi,%%rdx,8) \n"
|
|
|
|
|
|
|
|
"inc %%rdx \n"
|
|
|
|
"dec %%rcx \n"
|
|
|
|
"jnz 1b \n"
|
|
|
|
|
|
|
|
"adc %%rcx, %%rcx \n" // rcx has the cf state
|
|
|
|
|
|
|
|
"or %%r8, %%r8 \n"
|
|
|
|
"jz 3f \n"
|
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
"xor %%rbx, %%rbx \n" // ebx = 0
|
|
|
|
"neg %%rcx \n" // setting cf from rcx
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02:00
|
|
|
"mov %%r8, %%rcx \n" // rcx=rest and is != 0
|
|
|
|
"2: \n"
|
|
|
|
"mov (%%rsi, %%rdx, 8), %%rax \n"
|
|
|
|
"sbb %%rbx, %%rax \n"
|
|
|
|
"mov %%rax, (%%rdi, %%rdx, 8) \n"
|
|
|
|
|
|
|
|
"inc %%rdx \n"
|
|
|
|
"dec %%rcx \n"
|
|
|
|
"jnz 2b \n"
|
|
|
|
|
|
|
|
"adc %%rcx, %%rcx \n"
|
|
|
|
"3: \n"
|
|
|
|
|
|
|
|
: "=a" (dummy1), "=b" (dummy2), "=c" (c), "=d" (dummy3)
|
|
|
|
: "1" (ss2), "2" (ss2_size), "3" (rest), "S" (ss1), "D" (result)
|
|
|
|
: "%r8", "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_VECTOR_LOGC("UInt::SubVector", c, result, ss1_size)
|
2009-05-01 16:53:21 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
added: uint UInt::Mul3(const UInt<value_size> & ss2)
void UInt::Mul3Big(const UInt<value_size> & ss2, UInt<value_size*2> & result)
a new multiplication algorithm: Karatsuba multiplication,
on a vector UInt<100> with all items different from zero this algorithm is faster
about 3 times than Mul2Big(), and on a vector UInt<1000> with all items different from
zero this algorithm is faster more than 5 times than Mul2Big()
(measured on 32bit platform with GCC 4.3.3 with -O3 and -DTTMATH_RELEASE)
added: uint MulFastest(const UInt<value_size> & ss2)
void MulFastestBig(const UInt<value_size> & ss2, UInt<value_size*2> & result)
those methods are trying to select the fastest multiplication algorithm
changed: uint Mul(const UInt<value_size> & ss2, uint algorithm = 100)
void MulBig(const UInt<value_size> & ss2, UInt<value_size*2> & result, uint algorithm = 100)
those methods by default use MulFastest() and MulFastestBig()
changed: changed a little Mul2Big() to cooperate with Mul3Big()
changed: names of methods in macros TTMATH_LOG()
added: uint AddVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
uint SubVector(const uint * ss1, const uint * ss2, uint ss1_size, uint ss2_size, uint * result)
three forms: asm x86, asm x86_64, no-asm
those methods are used by the Karatsuba multiplication algorithm
git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@148 e52654a7-88a9-db11-a3e9-0013d4bc506e
2009-05-16 00:27:04 +02: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
|
|
|
|
|
|
|
|
***this method is created only on a 64bit platform***
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
uint UInt<value_size>::Rcl2_one(uint c)
|
|
|
|
{
|
2009-05-05 09:20:10 +02:00
|
|
|
sint b = value_size;
|
|
|
|
uint * p1 = table;
|
2009-05-17 02:04:42 +02:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
2008-10-31 00:38:24 +01:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_rcl_x64(p1,b,c);
|
2009-09-07 04:03:00 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy, dummy2;
|
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
"xorq %%rdx, %%rdx \n" // rdx=0
|
2009-05-17 02:04:42 +02:00
|
|
|
"negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
2008-10-31 00:38:24 +01:00
|
|
|
|
|
|
|
"1: \n"
|
|
|
|
"rclq $1, (%%rbx, %%rdx, 8) \n"
|
|
|
|
|
|
|
|
"incq %%rdx \n"
|
|
|
|
"decq %%rcx \n"
|
|
|
|
"jnz 1b \n"
|
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
"adcq %%rcx, %%rcx \n"
|
2008-10-31 00:38:24 +01:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
: "=c" (c), "=a" (dummy), "=d" (dummy2)
|
2009-05-17 02:04:42 +02:00
|
|
|
: "0" (b), "1" (c), "b" (p1)
|
2008-10-31 00:38:24 +01:00
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::Rcl2_one", c)
|
2008-10-31 00:38:24 +01:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method moves all bits into the right hand side
|
|
|
|
c -> this -> return value
|
|
|
|
|
|
|
|
the highest *bit* will be held the 'c' and
|
|
|
|
the state of one additional bit (on the right hand side)
|
|
|
|
will be returned
|
|
|
|
|
|
|
|
for example:
|
|
|
|
let this is 000000010
|
|
|
|
after Rcr2_one(1) there'll be 100000001 and Rcr2_one returns 0
|
|
|
|
|
|
|
|
***this method is created only on a 64bit platform***
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
uint UInt<value_size>::Rcr2_one(uint c)
|
|
|
|
{
|
2009-05-05 09:20:10 +02:00
|
|
|
sint b = value_size;
|
|
|
|
uint * p1 = table;
|
2009-05-17 02:04:42 +02:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_rcr_x64(p1,b,c);
|
2008-10-31 00:38:24 +01:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy;
|
|
|
|
|
2008-10-31 00:38:24 +01:00
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
"negq %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
2008-10-31 00:38:24 +01:00
|
|
|
|
|
|
|
"1: \n"
|
|
|
|
"rcrq $1, -8(%%rbx, %%rcx, 8) \n"
|
|
|
|
|
|
|
|
"decq %%rcx \n"
|
|
|
|
"jnz 1b \n"
|
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
"adcq %%rcx, %%rcx \n"
|
2008-10-31 00:38:24 +01:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
: "=c" (c), "=a" (dummy)
|
2009-05-17 02:04:42 +02:00
|
|
|
: "0" (b), "1" (c), "b" (p1)
|
2008-10-31 00:38:24 +01:00
|
|
|
: "cc", "memory" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::Rcr2_one", c)
|
2008-10-31 00:38:24 +01:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +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-29 18:58:18 +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
|
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-04-12 00:14:17 +02:00
|
|
|
for example:
|
|
|
|
let this is 001010000
|
|
|
|
after Rcl2(3, 1) there'll be 010000111 and Rcl2 returns 1
|
|
|
|
|
|
|
|
***this method is created only on a 64bit platform***
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
template<uint value_size>
|
2007-04-12 00:14:17 +02:00
|
|
|
uint UInt<value_size>::Rcl2(uint bits, uint c)
|
2007-01-29 18:58:18 +01:00
|
|
|
{
|
2007-04-12 00:14:17 +02:00
|
|
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
uint b = value_size;
|
|
|
|
uint * p1 = table;
|
2009-05-17 02:04:42 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_rcl2_x64(p1,b,bits,c);
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy, dummy2, dummy3;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"movq %%rcx, %%rsi \n"
|
|
|
|
"movq $64, %%rcx \n"
|
|
|
|
"subq %%rsi, %%rcx \n"
|
|
|
|
"movq $-1, %%rdx \n"
|
|
|
|
"shrq %%cl, %%rdx \n"
|
2009-05-05 09:20:10 +02:00
|
|
|
"movq %%rdx, %%r8 \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"movq %%rsi, %%rcx \n"
|
|
|
|
|
|
|
|
"xorq %%rdx, %%rdx \n"
|
|
|
|
"movq %%rdx, %%rsi \n"
|
|
|
|
"orq %%rax, %%rax \n"
|
2009-05-05 09:20:10 +02:00
|
|
|
"cmovnz %%r8, %%rsi \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
|
|
|
|
"1: \n"
|
|
|
|
"rolq %%cl, (%%rbx,%%rdx,8) \n"
|
|
|
|
|
|
|
|
"movq (%%rbx,%%rdx,8), %%rax \n"
|
2009-05-05 09:20:10 +02:00
|
|
|
"andq %%r8, %%rax \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"xorq %%rax, (%%rbx,%%rdx,8) \n"
|
|
|
|
"orq %%rsi, (%%rbx,%%rdx,8) \n"
|
|
|
|
"movq %%rax, %%rsi \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"incq %%rdx \n"
|
|
|
|
"decq %%rdi \n"
|
|
|
|
"jnz 1b \n"
|
|
|
|
|
|
|
|
"and $1, %%rax \n"
|
2007-04-12 00:14:17 +02:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
: "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
|
2009-05-17 02:04:42 +02:00
|
|
|
: "0" (c), "1" (b), "b" (p1), "c" (bits)
|
2009-05-05 09:20:10 +02:00
|
|
|
: "%r8", "cc", "memory" );
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::Rcl2", c)
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2007-04-12 00:14:17 +02:00
|
|
|
this method moves all bits into the right hand side
|
|
|
|
C -> this -> return value
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2007-04-12 00:14:17 +02:00
|
|
|
the highest *bits* will be held the 'c' and
|
|
|
|
the state of one additional bit (on the right hand side)
|
|
|
|
will be returned
|
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-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
|
|
|
|
|
|
|
|
***this method is created only on a 64bit platform***
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
template<uint value_size>
|
2007-04-12 00:14:17 +02:00
|
|
|
uint UInt<value_size>::Rcr2(uint bits, uint c)
|
2007-01-29 18:58:18 +01:00
|
|
|
{
|
2007-04-12 00:14:17 +02:00
|
|
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
sint b = value_size;
|
|
|
|
uint * p1 = table;
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
2009-09-12 01:55:44 +02:00
|
|
|
c = ttmath_rcr2_x64(p1,b,bits,c);
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
2009-09-07 04:03:00 +02:00
|
|
|
uint dummy, dummy2, dummy3;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
__asm__ __volatile__(
|
|
|
|
|
2008-10-29 22:54:27 +01:00
|
|
|
"movq %%rcx, %%rsi \n"
|
|
|
|
"movq $64, %%rcx \n"
|
|
|
|
"subq %%rsi, %%rcx \n"
|
|
|
|
"movq $-1, %%rdx \n"
|
|
|
|
"shlq %%cl, %%rdx \n"
|
2009-05-05 09:20:10 +02:00
|
|
|
"movq %%rdx, %%R8 \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"movq %%rsi, %%rcx \n"
|
|
|
|
|
|
|
|
"xorq %%rdx, %%rdx \n"
|
|
|
|
"movq %%rdx, %%rsi \n"
|
|
|
|
"addq %%rdi, %%rdx \n"
|
|
|
|
"decq %%rdx \n"
|
|
|
|
"orq %%rax, %%rax \n"
|
2009-05-05 09:20:10 +02:00
|
|
|
"cmovnz %%R8, %%rsi \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
|
|
|
|
"1: \n"
|
|
|
|
"rorq %%cl, (%%rbx,%%rdx,8) \n"
|
|
|
|
|
|
|
|
"movq (%%rbx,%%rdx,8), %%rax \n"
|
2009-05-17 02:04:42 +02:00
|
|
|
"andq %%R8, %%rax \n"
|
2008-10-29 22:54:27 +01:00
|
|
|
"xorq %%rax, (%%rbx,%%rdx,8) \n"
|
|
|
|
"orq %%rsi, (%%rbx,%%rdx,8) \n"
|
|
|
|
"movq %%rax, %%rsi \n"
|
|
|
|
|
|
|
|
"decq %%rdx \n"
|
|
|
|
"decq %%rdi \n"
|
|
|
|
"jnz 1b \n"
|
|
|
|
|
|
|
|
"rolq $1, %%rax \n"
|
|
|
|
"andq $1, %%rax \n"
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-05 09:20:10 +02:00
|
|
|
: "=a" (c), "=D" (dummy), "=S" (dummy2), "=d" (dummy3)
|
|
|
|
: "0" (c), "1" (b), "b" (p1), "c" (bits)
|
|
|
|
: "%r8", "cc", "memory" );
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-10-03 03:10:08 +02:00
|
|
|
TTMATH_LOGC("UInt::Rcr2", c)
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
2009-05-08 20:14:00 +02:00
|
|
|
this method returns the number of the highest set bit in one 64-bit word
|
2007-01-29 18:58:18 +01:00
|
|
|
if the 'x' is zero this method returns '-1'
|
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 created only on a 64bit platform***
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
sint UInt<value_size>::FindLeadingBitInWord(uint x)
|
|
|
|
{
|
2009-05-17 02:04:42 +02:00
|
|
|
sint result;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
|
|
|
unsigned long nIndex = 0;
|
|
|
|
|
|
|
|
if( _BitScanReverse64(&nIndex,x) == 0 )
|
|
|
|
result = -1;
|
|
|
|
else
|
|
|
|
result = nIndex;
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
2009-05-17 02:04:42 +02:00
|
|
|
uint dummy;
|
|
|
|
|
2009-05-27 01:13:22 +02:00
|
|
|
__asm__ (
|
|
|
|
|
|
|
|
"movq $-1, %1 \n"
|
|
|
|
"bsrq %2, %0 \n"
|
|
|
|
"cmovz %1, %0 \n"
|
|
|
|
|
|
|
|
: "=r" (result), "=&r" (dummy)
|
|
|
|
: "r" (x)
|
|
|
|
: "cc" );
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method sets a special bit in the 'value'
|
2009-03-11 20:05:13 +01:00
|
|
|
and returns the last state of the bit (zero or one)
|
2007-01-29 18:58:18 +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 is created only on a 64bit platform***
|
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
bit is from <0,63>
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
e.g.
|
2009-03-11 20:05:13 +01:00
|
|
|
uint x = 100;
|
|
|
|
uint bit = SetBitInWord(x, 3);
|
|
|
|
now: x = 108 and bit = 0
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
template<uint value_size>
|
2009-03-11 20:05:13 +01:00
|
|
|
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
2007-01-29 18:58:18 +01:00
|
|
|
{
|
2009-03-11 20:05:13 +01:00
|
|
|
TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
|
|
|
|
|
|
|
|
uint old_bit;
|
|
|
|
uint v = value;
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
|
|
|
#endif
|
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#ifdef _MSC_VER
|
|
|
|
old_bit = _bittestandset64((__int64*)&value,bit) != 0;
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
__asm__ (
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
"btsq %%rbx, %%rax \n"
|
2009-03-11 20:05:13 +01:00
|
|
|
"setc %%bl \n"
|
|
|
|
"movzx %%bl, %%rbx \n"
|
|
|
|
|
|
|
|
: "=a" (v), "=b" (old_bit)
|
2009-05-17 02:04:42 +02:00
|
|
|
: "0" (v), "1" (bit)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "cc" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2009-03-11 20:05:13 +01:00
|
|
|
value = v;
|
|
|
|
|
|
|
|
return old_bit;
|
2007-01-29 18:58:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* Multiplication
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
2009-05-08 20:14:00 +02:00
|
|
|
multiplication: result_high:result_low = a * b
|
|
|
|
result_high - higher word of the result
|
|
|
|
result_low - lower word of the result
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
this methos never returns a carry
|
2009-05-08 20:14:00 +02:00
|
|
|
this method is used in the second version of the multiplication algorithms
|
2007-01-29 18:58:18 +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 is created only on a 64bit platform***
|
2007-01-29 18:58:18 +01:00
|
|
|
*/
|
|
|
|
template<uint value_size>
|
2009-05-08 20:14:00 +02:00
|
|
|
void UInt<value_size>::MulTwoWords(uint a, uint b, uint * result_high, uint * result_low)
|
2007-01-29 18:58:18 +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
|
|
|
|
using gcc and options like -O
|
|
|
|
*/
|
2009-05-17 02:04:42 +02:00
|
|
|
uint result1_;
|
|
|
|
uint result2_;
|
2007-01-29 18:58:18 +01:00
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
result1_ = _umul128(a,b,&result2_);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
__asm__ (
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
"mulq %%rdx \n"
|
|
|
|
|
|
|
|
: "=a" (result1_), "=d" (result2_)
|
2009-05-17 02:04:42 +02:00
|
|
|
: "0" (a), "1" (b)
|
2007-01-29 18:58:18 +01:00
|
|
|
: "cc" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2009-05-08 20:14:00 +02:00
|
|
|
*result_low = result1_;
|
|
|
|
*result_high = result2_;
|
2007-01-29 18:58:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
*
|
|
|
|
* Division
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
this method calculates 64bits word a:b / 32bits c (a higher, b lower word)
|
|
|
|
r = a:b / c and rest - remainder
|
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 created only on a 64bit platform***
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
*
|
|
|
|
* WARNING:
|
|
|
|
* if r (one word) is too small for the result or c is equal zero
|
|
|
|
* there'll be a hardware interruption (0)
|
|
|
|
* and probably the end of your program
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
template<uint value_size>
|
|
|
|
void UInt<value_size>::DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest)
|
|
|
|
{
|
2009-05-17 02:04:42 +02:00
|
|
|
uint r_;
|
|
|
|
uint rest_;
|
2007-01-29 18:58:18 +01:00
|
|
|
/*
|
|
|
|
these variables have similar meaning like those in
|
|
|
|
the multiplication algorithm MulTwoWords
|
|
|
|
*/
|
|
|
|
|
2009-05-04 22:51:12 +02:00
|
|
|
TTMATH_ASSERT( c != 0 )
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
#if !defined(__GNUC__) && !defined(_MSC_VER)
|
|
|
|
#error "another compiler than GCC or Microsoft VC is currently not supported in 64bit mode, you can compile with TTMATH_NOASM macro"
|
2007-01-29 18:58:18 +01:00
|
|
|
#endif
|
|
|
|
|
2009-09-07 04:03:00 +02:00
|
|
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
2009-09-12 01:55:44 +02:00
|
|
|
ttmath_div_x64(&a,&b,c);
|
2009-09-07 04:03:00 +02:00
|
|
|
r_ = a;
|
|
|
|
rest_ = b;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-01-29 18:58:18 +01:00
|
|
|
#ifdef __GNUC__
|
|
|
|
|
2009-05-17 02:04:42 +02:00
|
|
|
__asm__ (
|
2007-01-29 18:58:18 +01:00
|
|
|
|
|
|
|
"divq %%rcx \n"
|
|
|
|
|
|
|
|
: "=a" (r_), "=d" (rest_)
|
|
|
|
: "d" (a), "a" (b), "c" (c)
|
|
|
|
: "cc" );
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
*r = r_;
|
|
|
|
*rest = rest_;
|
|
|
|
}
|
|
|
|
|
|
|
|
} //namespace
|
2009-05-04 22:51:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
#endif //ifdef TTMATH_PLATFORM64
|
|
|
|
#endif //ifndef TTMATH_NOASM
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|