fixed: there was a TTMATH_REREFENCE_ASSERT error in Big::PowUInt() caused by: start.Mul(start)
fixed: Big::Add incorrectly rounded 'this' when both exponents were equal it caused that sometimes when adding a zero the result has changed this had impact among other things on FromString() method "0,8" had different binary representation from "0,80" changed: renamed: Big::PowUInt(UInt<pow_size> pow) -> Big::Pow(UInt<pow_size> pow) it returns 2 when there is: 0^0 changed: renamed: Big::PowInt(Int<pow_size> pow) -> Big::Pow(Int<pow_size> pow) it returns 2 when there is: 0^0 or 0^(-something) changed: renamed: Big::PowBUInt() -> PowUInt(), Big::PowBInt() -> Big::PowInt() they return 2 when the arguments are incorrect (like above) changed: UInt::SetBitInWord(uint & value, uint bit) is taking the first argument by a reference now, the specific bit is set in the 'value' and the method returns the last state of the bit (zero or one) added: UInt::GetBit(uint bit_index) - returning the state of the specific bit changed: UInt::SetBit(uint bit_index) - it's using TTMATH_ASSERT now changed: Big::Mod2() - it's using mantissa.GetBit() now added: Big::operator=(double) and Big::Big(double) added: TTMATH_ASSERT somewhere in ttmathuint64.h added: UInt::Pow(UInt<value_size> pow) and Int::Pow(Int<value_size> pow) git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@104 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
404727f3de
commit
978815f12d
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -59,7 +59,52 @@ void test_uint()
|
|||
int main()
|
||||
{
|
||||
using namespace ttmath;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Int<300> uu, oo;
|
||||
|
||||
uu = -2;
|
||||
oo = 5;
|
||||
|
||||
uint ccc = uu.Pow(oo);
|
||||
|
||||
if( ccc )
|
||||
std::cout << "carry: " << ccc << std::endl;
|
||||
else
|
||||
std::cout << uu << std::endl;
|
||||
return 0;
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
UInt<2> w = 100;
|
||||
w.GetBit(64);
|
||||
std::cout << w << std::endl;
|
||||
|
||||
return 0;
|
||||
*/
|
||||
|
||||
/*
|
||||
uint q = 100;
|
||||
uint last = UInt<3>::SetBitInWord(q, 3);
|
||||
std::cout << "nowa wartosc: " << q << ", wczesniejszy bit: " << last << std::endl;
|
||||
return 0;
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
Big<1, 3> a = -26;
|
||||
Int<3> b = -8;
|
||||
|
||||
uint c = a.Pow(b);
|
||||
|
||||
if ( c )
|
||||
std::cout << "carry: " << c << std::endl;
|
||||
else
|
||||
std::cout << a << std::endl;
|
||||
return 0;
|
||||
*/
|
||||
|
||||
test_uint();
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -561,9 +561,9 @@ public:
|
|||
}
|
||||
|
||||
|
||||
if( exp_offset > mantissa_size_in_bits )
|
||||
if( exp_offset >= mantissa_size_in_bits )
|
||||
{
|
||||
// the second value is too short for taking into consideration in the sum
|
||||
// the second value is too small for taking into consideration in the sum
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
@ -572,13 +572,6 @@ public:
|
|||
// (2) moving 'exp_offset' times
|
||||
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// (3)
|
||||
// exp_offset == mantissa_size_in_bits
|
||||
// we're rounding 'this' about one (up or down depending on a ss2 sign)
|
||||
ss2.mantissa.SetOne();
|
||||
}
|
||||
|
||||
|
||||
if( IsSign() == ss2.IsSign() )
|
||||
|
@ -594,8 +587,8 @@ public:
|
|||
{
|
||||
// values have different signs
|
||||
// there shouldn't be a carry here because
|
||||
// (1) (2) and (3) guarantee that the mantissa of this
|
||||
// is greater than the mantissa of the ss2
|
||||
// (1) (2) guarantee that the mantissa of this
|
||||
// is greater than or equal to the mantissa of the ss2
|
||||
uint c_temp = mantissa.Sub(ss2.mantissa);
|
||||
|
||||
TTMATH_ASSERT( c_temp == 0 )
|
||||
|
@ -653,7 +646,7 @@ public:
|
|||
|
||||
if( exp_offset >= mantissa_size_in_bits )
|
||||
{
|
||||
// the second value is too short
|
||||
// the second value is too small
|
||||
SetZero();
|
||||
return 0;
|
||||
}
|
||||
|
@ -700,7 +693,7 @@ public:
|
|||
}
|
||||
|
||||
if( exp_offset >= mantissa_size_in_bits )
|
||||
// the second value is too short
|
||||
// the second value is too small
|
||||
return 0;
|
||||
|
||||
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
||||
|
@ -745,7 +738,7 @@ public:
|
|||
}
|
||||
|
||||
if( exp_offset >= mantissa_size_in_bits )
|
||||
// the second value is too short
|
||||
// the second value is too small
|
||||
return 0;
|
||||
|
||||
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
||||
|
@ -966,18 +959,23 @@ public:
|
|||
|
||||
/*!
|
||||
power this = this ^ pow
|
||||
pow without a sign
|
||||
(pow without a sign)
|
||||
|
||||
binary algorithm (r-to-l)
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry
|
||||
2 - incorrect arguments (0^0)
|
||||
*/
|
||||
template<uint pow_size>
|
||||
uint PowUInt(UInt<pow_size> pow)
|
||||
uint Pow(UInt<pow_size> pow)
|
||||
{
|
||||
if(pow.IsZero() && IsZero())
|
||||
// we don't define zero^zero
|
||||
return 1;
|
||||
return 2;
|
||||
|
||||
Big<exp, man> start(*this);
|
||||
Big<exp, man> start(*this), start_temp;
|
||||
Big<exp, man> result;
|
||||
result.SetOne();
|
||||
|
||||
|
@ -987,7 +985,8 @@ public:
|
|||
if( result.Mul(start) )
|
||||
return 1;
|
||||
|
||||
if( start.Mul(start) )
|
||||
start_temp = start;
|
||||
if( start.Mul(start_temp) )
|
||||
return 1;
|
||||
|
||||
pow.Rcr(1);
|
||||
|
@ -1001,27 +1000,31 @@ public:
|
|||
|
||||
/*!
|
||||
power this = this ^ pow
|
||||
p can be with a sign
|
||||
p can be negative
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry
|
||||
2 - incorrect arguments 0^0 or 0^(-something)
|
||||
*/
|
||||
template<uint pow_size>
|
||||
uint PowInt(Int<pow_size> pow)
|
||||
uint Pow(Int<pow_size> pow)
|
||||
{
|
||||
if( !pow.IsSign() )
|
||||
return PowUInt(pow);
|
||||
|
||||
return Pow( UInt<pow_size>(pow) );
|
||||
|
||||
if( IsZero() )
|
||||
// if 'p' is negative then
|
||||
// 'this' must be different from zero
|
||||
return 1;
|
||||
return 2;
|
||||
|
||||
if( pow.ChangeSign() )
|
||||
return 1;
|
||||
|
||||
Big<exp, man> t(*this);
|
||||
if( t.PowUInt(pow) )
|
||||
return 1;
|
||||
uint c_temp = t.Pow( UInt<pow_size>(pow) );
|
||||
if( c_temp > 0 )
|
||||
return c_temp;
|
||||
|
||||
SetOne();
|
||||
if( Div(t) )
|
||||
|
@ -1032,33 +1035,40 @@ public:
|
|||
|
||||
|
||||
/*!
|
||||
this method returns true if 'this' mod 2 is equal one
|
||||
this method returns: 'this' mod 2
|
||||
(either zero or one)
|
||||
|
||||
this method is much faster than using Mod( object_with_value_two )
|
||||
*/
|
||||
bool Mod2() const
|
||||
uint Mod2() const
|
||||
{
|
||||
if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) )
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
sint exp_int = exponent.ToInt();
|
||||
// 'exp_int' is negative (or zero), we set its as positive
|
||||
// 'exp_int' is negative (or zero), we set it as positive
|
||||
exp_int = -exp_int;
|
||||
|
||||
// !!! here we'll use a new method (method for testing a bit)
|
||||
uint value = mantissa.table[ exp_int / TTMATH_BITS_PER_UINT ];
|
||||
value >>= (uint(exp_int) % TTMATH_BITS_PER_UINT);
|
||||
|
||||
return bool(value & 1);
|
||||
return mantissa.GetBit(exp_int);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
power this = this ^ abs([pow])
|
||||
pow without a sign and without a fraction
|
||||
pow is treated as a value without a sign and without a fraction
|
||||
if pow has a sign then the method pow.Abs() is used
|
||||
if pow has a fraction the fraction is skipped (not used in calculation)
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry
|
||||
2 - incorrect arguments (0^0)
|
||||
*/
|
||||
uint PowBUInt(Big<exp, man> pow)
|
||||
uint PowUInt(Big<exp, man> pow)
|
||||
{
|
||||
if( pow.IsZero() && IsZero() )
|
||||
return 1;
|
||||
return 2;
|
||||
|
||||
if( pow.IsSign() )
|
||||
pow.Abs();
|
||||
|
@ -1070,7 +1080,7 @@ public:
|
|||
|
||||
e_one.SetOne();
|
||||
one.SetOne();
|
||||
result.SetOne();
|
||||
result = one;
|
||||
|
||||
while( pow >= one )
|
||||
{
|
||||
|
@ -1093,24 +1103,30 @@ public:
|
|||
|
||||
/*!
|
||||
power this = this ^ [pow]
|
||||
pow without a fraction
|
||||
pow is treated as a value without a fraction
|
||||
pow can be negative
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry
|
||||
2 - incorrect arguments 0^0 or 0^(-something)
|
||||
*/
|
||||
uint PowBInt(const Big<exp, man> & pow)
|
||||
uint PowInt(const Big<exp, man> & pow)
|
||||
{
|
||||
TTMATH_REFERENCE_ASSERT( pow )
|
||||
|
||||
if( !pow.IsSign() )
|
||||
return PowBUInt(pow);
|
||||
return PowUInt(pow);
|
||||
|
||||
if( IsZero() )
|
||||
// if 'pow' is negative then
|
||||
// 'this' must be different from zero
|
||||
return 1;
|
||||
return 2;
|
||||
|
||||
Big<exp, man> temp(*this);
|
||||
if( temp.PowBUInt(pow) )
|
||||
return 1;
|
||||
uint c_temp = temp.PowUInt(pow);
|
||||
if( c_temp > 0 )
|
||||
return c_temp;
|
||||
|
||||
SetOne();
|
||||
if( Div(temp) )
|
||||
|
@ -1122,13 +1138,13 @@ public:
|
|||
|
||||
/*!
|
||||
power this = this ^ pow
|
||||
this *must* be greater than zero (this > 0)
|
||||
this must be greater than zero (this > 0)
|
||||
pow can be negative and with fraction
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry
|
||||
2 - incorrect argument ('this')
|
||||
2 - incorrect argument ('this' <= 0)
|
||||
*/
|
||||
uint PowFrac(const Big<exp, man> & pow)
|
||||
{
|
||||
|
@ -1147,6 +1163,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
power this = this ^ pow
|
||||
pow can be negative and with fraction
|
||||
|
@ -1175,7 +1192,7 @@ public:
|
|||
pow_frac.RemainFraction();
|
||||
|
||||
if( pow_frac.IsZero() )
|
||||
return PowBInt( pow );
|
||||
return PowInt( pow );
|
||||
|
||||
// pow is with fraction (not integer)
|
||||
// result = e^(pow * ln(this) ) where 'this' must be greater than 0
|
||||
|
@ -1318,7 +1335,7 @@ public:
|
|||
else
|
||||
{
|
||||
ExpSurrounding0(m);
|
||||
c += PowBUInt(e_);
|
||||
c += PowUInt(e_);
|
||||
}
|
||||
|
||||
return (c==0)? 0 : 1;
|
||||
|
@ -1793,7 +1810,7 @@ public:
|
|||
// where "1.F" is intended to represent the binary number
|
||||
// created by prefixing F with an implicit leading 1 and a binary point.
|
||||
|
||||
FromDouble_SetExpAndMan(bool(temp.u[1] & 0x80000000u),
|
||||
FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
|
||||
e - 1023 - man*TTMATH_BITS_PER_UINT + 1, 0x80000000u,
|
||||
m1, m2);
|
||||
|
||||
|
@ -1815,7 +1832,7 @@ public:
|
|||
m.table[0] = m2;
|
||||
uint moved = m.CompensationToLeft();
|
||||
|
||||
FromDouble_SetExpAndMan(bool(temp.u[1] & 0x80000000u),
|
||||
FromDouble_SetExpAndMan((temp.u[1] & 0x80000000u) != 0,
|
||||
e - 1022 - man*TTMATH_BITS_PER_UINT + 1 - moved, 0,
|
||||
m.table[1], m.table[2]);
|
||||
}
|
||||
|
@ -1906,7 +1923,7 @@ public:
|
|||
// where "1.F" is intended to represent the binary number
|
||||
// created by prefixing F with an implicit leading 1 and a binary point.
|
||||
|
||||
FromDouble_SetExpAndMan(bool(temp.u & 0x8000000000000000ul),
|
||||
FromDouble_SetExpAndMan((temp.u & 0x8000000000000000ul) != 0,
|
||||
e - 1023 - man*TTMATH_BITS_PER_UINT + 1,
|
||||
0x8000000000000000ul, m);
|
||||
|
||||
|
@ -2118,6 +2135,17 @@ public:
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
an operator= for converting 'double' to this class
|
||||
*/
|
||||
Big<exp, man> & operator=(double value)
|
||||
{
|
||||
FromDouble(value);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
a constructor for converting 'sint' to this class
|
||||
*/
|
||||
|
@ -2135,6 +2163,15 @@ public:
|
|||
}
|
||||
|
||||
|
||||
/*!
|
||||
a constructor for converting 'double' to this class
|
||||
*/
|
||||
Big(double value)
|
||||
{
|
||||
FromDouble(value);
|
||||
}
|
||||
|
||||
|
||||
#ifdef TTMATH_PLATFORM64
|
||||
|
||||
/*!
|
||||
|
@ -3324,7 +3361,7 @@ private:
|
|||
new_exponent.ChangeSign();
|
||||
|
||||
temp = 10;
|
||||
c += temp.PowBInt( new_exponent );
|
||||
c += temp.PowInt( new_exponent );
|
||||
c += Mul(temp);
|
||||
|
||||
return (c==0)? 0 : 1;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -469,6 +469,70 @@ public:
|
|||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
/*!
|
||||
power this = this ^ pow
|
||||
this can be negative
|
||||
pow is >= 0
|
||||
*/
|
||||
uint Pow2(const Int<value_size> & pow)
|
||||
{
|
||||
bool was_sign = IsSign();
|
||||
uint c = 0;
|
||||
|
||||
if( was_sign )
|
||||
c += Abs();
|
||||
|
||||
uint c_temp = UInt<value_size>::Pow(pow);
|
||||
if( c_temp > 0 )
|
||||
return c_temp; // c_temp can be: 0, 1 or 2
|
||||
|
||||
if( was_sign && (pow.table[0] & 1) == 1 )
|
||||
// negative value to the power of odd number is negative
|
||||
c += ChangeSign();
|
||||
|
||||
return (c==0)? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
/*!
|
||||
power this = this ^ pow
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry
|
||||
2 - incorrect arguments 0^0 or 0^(-something)
|
||||
*/
|
||||
uint Pow(Int<value_size> pow)
|
||||
{
|
||||
if( !pow.IsSign() )
|
||||
return Pow2(pow);
|
||||
|
||||
if( UInt<value_size>::IsZero() )
|
||||
// if 'p' is negative then
|
||||
// 'this' must be different from zero
|
||||
return 2;
|
||||
|
||||
if( pow.ChangeSign() )
|
||||
return 1;
|
||||
|
||||
Int<value_size> t(*this);
|
||||
uint c_temp = t.Pow2(pow);
|
||||
if( c_temp > 0 )
|
||||
return c_temp;
|
||||
|
||||
UInt<value_size>::SetOne();
|
||||
if( Div(t) )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
*
|
||||
|
|
|
@ -64,8 +64,8 @@
|
|||
*/
|
||||
#define TTMATH_MAJOR_VER 0
|
||||
#define TTMATH_MINOR_VER 8
|
||||
#define TTMATH_REVISION_VER 2
|
||||
#define TTMATH_PRERELEASE_VER 0
|
||||
#define TTMATH_REVISION_VER 3
|
||||
#define TTMATH_PRERELEASE_VER 1
|
||||
|
||||
|
||||
/*!
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -950,9 +950,6 @@ private:
|
|||
*/
|
||||
uint Rcl2(uint bits, uint c)
|
||||
{
|
||||
if( bits == 0 )
|
||||
return 0;
|
||||
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
|
@ -1078,9 +1075,6 @@ private:
|
|||
*/
|
||||
uint Rcr2(uint bits, uint c)
|
||||
{
|
||||
if( bits == 0 )
|
||||
return 0;
|
||||
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
|
@ -1503,30 +1497,40 @@ public:
|
|||
|
||||
#ifdef TTMATH_PLATFORM32
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this method sets a special bit in the 'value'
|
||||
and returns the result
|
||||
and returns the last state of the bit (zero or one)
|
||||
|
||||
bit is from <0,31>
|
||||
|
||||
e.g.
|
||||
SetBitInWord(0,0) = 1
|
||||
SetBitInWord(0,2) = 4
|
||||
SetBitInWord(10, 8) = 266
|
||||
uint x = 100;
|
||||
uint bit = SetBitInWord(x, 3);
|
||||
now: x = 108 and bit = 0
|
||||
*/
|
||||
static uint SetBitInWord(uint value, uint bit)
|
||||
static uint SetBitInWord(uint & value, uint bit)
|
||||
{
|
||||
TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
|
||||
|
||||
uint old_bit;
|
||||
uint v = value;
|
||||
|
||||
#ifndef __GNUC__
|
||||
__asm
|
||||
{
|
||||
push ebx
|
||||
push eax
|
||||
mov eax, [value]
|
||||
|
||||
mov eax, [v]
|
||||
mov ebx, [bit]
|
||||
bts eax, ebx
|
||||
mov [value], eax
|
||||
mov [v], eax
|
||||
|
||||
setc bl
|
||||
movzx ebx, bl
|
||||
mov [old_bit], ebx
|
||||
|
||||
pop eax
|
||||
pop ebx
|
||||
}
|
||||
|
@ -1536,15 +1540,20 @@ public:
|
|||
#ifdef __GNUC__
|
||||
__asm__ __volatile__(
|
||||
|
||||
"btsl %2,%0 \n"
|
||||
"btsl %%ebx, %%eax \n"
|
||||
|
||||
: "=R" (value)
|
||||
: "0" (value), "R" (bit)
|
||||
"setc %%bl \n"
|
||||
"movzx %%bl, %%ebx \n"
|
||||
|
||||
: "=a" (v), "=b" (old_bit)
|
||||
: "0" (v), "1" (bit)
|
||||
: "cc" );
|
||||
|
||||
#endif
|
||||
|
||||
return value;
|
||||
value = v;
|
||||
|
||||
return old_bit;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1555,15 +1564,33 @@ public:
|
|||
|
||||
bit_index bigger or equal zero
|
||||
*/
|
||||
void SetBit(uint bit_index)
|
||||
uint GetBit(uint bit_index) const
|
||||
{
|
||||
TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
|
||||
|
||||
uint index = bit_index / TTMATH_BITS_PER_UINT;
|
||||
if( index >= value_size )
|
||||
return;
|
||||
uint bit = bit_index % TTMATH_BITS_PER_UINT;
|
||||
|
||||
bit_index %= TTMATH_BITS_PER_UINT;
|
||||
uint temp = table[index];
|
||||
|
||||
return SetBitInWord(temp, bit);
|
||||
}
|
||||
|
||||
table[index] = SetBitInWord(table[index], bit_index);
|
||||
|
||||
/*!
|
||||
setting the 'bit_index' bit
|
||||
and returning the last state of the bit
|
||||
|
||||
bit_index bigger or equal zero
|
||||
*/
|
||||
uint SetBit(uint bit_index)
|
||||
{
|
||||
TTMATH_ASSERT( bit_index < value_size * TTMATH_BITS_PER_UINT )
|
||||
|
||||
uint index = bit_index / TTMATH_BITS_PER_UINT;
|
||||
uint bit = bit_index % TTMATH_BITS_PER_UINT;
|
||||
|
||||
return SetBitInWord(table[index], bit);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2736,6 +2763,47 @@ private:
|
|||
|
||||
public:
|
||||
|
||||
|
||||
/*!
|
||||
power this = this ^ pow
|
||||
binary algorithm (r-to-l)
|
||||
|
||||
return values:
|
||||
0 - ok
|
||||
1 - carry or
|
||||
2 - incorrect argument (0^0)
|
||||
*/
|
||||
uint Pow(UInt<value_size> pow)
|
||||
{
|
||||
if(pow.IsZero() && IsZero())
|
||||
// we don't define zero^zero
|
||||
return 2;
|
||||
|
||||
UInt<value_size> start(*this), start_temp;
|
||||
UInt<value_size> result;
|
||||
result.SetOne();
|
||||
|
||||
while( !pow.IsZero() )
|
||||
{
|
||||
if( pow.table[0] & 1 )
|
||||
if( result.Mul(start) )
|
||||
return 1;
|
||||
|
||||
start_temp = start;
|
||||
// in the second Mul algorithm we can use start.Mul(start) directly (there is no TTMATH_ASSERT_REFERENCE there)
|
||||
if( start.Mul(start_temp) )
|
||||
return 1;
|
||||
|
||||
pow.Rcr2_one(0);
|
||||
}
|
||||
|
||||
*this = result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*!
|
||||
this method sets n first bits to value zero
|
||||
|
||||
|
@ -3607,7 +3675,7 @@ public:
|
|||
uint Sub(const UInt<value_size> & ss2, uint c=0);
|
||||
uint SubInt(uint value, uint index = 0);
|
||||
static sint FindLeadingBitInWord(uint x);
|
||||
static uint SetBitInWord(uint value, uint bit);
|
||||
static uint SetBitInWord(uint & value, uint bit);
|
||||
static void MulTwoWords(uint a, uint b, uint * result2, uint * result1);
|
||||
static void DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
||||
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -210,10 +210,12 @@ namespace ttmath
|
|||
register uint * p2 = const_cast<uint*>(ss2.table);
|
||||
|
||||
|
||||
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||
// this algorithm doesn't require it
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
/*
|
||||
|
@ -281,6 +283,8 @@ namespace ttmath
|
|||
register uint * p1 = table;
|
||||
register uint c;
|
||||
|
||||
TTMATH_ASSERT( index < value_size )
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
|
@ -361,6 +365,8 @@ namespace ttmath
|
|||
register uint * p1 = table;
|
||||
register uint c;
|
||||
|
||||
TTMATH_ASSERT( index < value_size - 1 )
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
|
@ -424,6 +430,9 @@ namespace ttmath
|
|||
register uint * p1 = table;
|
||||
register uint * p2 = const_cast<uint*>(ss2.table);
|
||||
|
||||
// we don't have to use TTMATH_REFERENCE_ASSERT here
|
||||
// this algorithm doesn't require it
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
|
@ -489,6 +498,8 @@ namespace ttmath
|
|||
register uint * p1 = table;
|
||||
register uint c;
|
||||
|
||||
TTMATH_ASSERT( index < value_size )
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
|
@ -559,8 +570,8 @@ namespace ttmath
|
|||
"push %%rdx \n"
|
||||
"push %%rcx \n"
|
||||
|
||||
"xorq %%rdx, %%rdx \n" // edx=0
|
||||
"neg %%rax \n" // CF=1 if eax!=0 , CF=0 if eax==0
|
||||
"xorq %%rdx, %%rdx \n" // rdx=0
|
||||
"neg %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
||||
|
||||
"1: \n"
|
||||
"rclq $1, (%%rbx, %%rdx, 8) \n"
|
||||
|
@ -616,7 +627,7 @@ namespace ttmath
|
|||
|
||||
"push %%rcx \n"
|
||||
|
||||
"neg %%rax \n" // CF=1 if eax!=0 , CF=0 if eax==0
|
||||
"neg %%rax \n" // CF=1 if rax!=0 , CF=0 if rax==0
|
||||
|
||||
"1: \n"
|
||||
"rcrq $1, -8(%%rbx, %%rcx, 8) \n"
|
||||
|
@ -658,9 +669,6 @@ namespace ttmath
|
|||
template<uint value_size>
|
||||
uint UInt<value_size>::Rcl2(uint bits, uint c)
|
||||
{
|
||||
if( bits == 0 )
|
||||
return 0;
|
||||
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
|
@ -739,9 +747,6 @@ namespace ttmath
|
|||
template<uint value_size>
|
||||
uint UInt<value_size>::Rcr2(uint bits, uint c)
|
||||
{
|
||||
if( bits == 0 )
|
||||
return 0;
|
||||
|
||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||
|
||||
register sint b = value_size;
|
||||
|
@ -843,20 +848,26 @@ namespace ttmath
|
|||
|
||||
/*!
|
||||
this method sets a special bit in the 'value'
|
||||
and returns the result
|
||||
and returns the last state of the bit (zero or one)
|
||||
|
||||
***this method is created only on a 64bit platform***
|
||||
|
||||
bit is from <0,31>
|
||||
bit is from <0,63>
|
||||
|
||||
e.g.
|
||||
SetBitInWord(0,0) = 1
|
||||
SetBitInWord(0,2) = 4
|
||||
SetBitInWord(10, 8) = 266
|
||||
uint x = 100;
|
||||
uint bit = SetBitInWord(x, 3);
|
||||
now: x = 108 and bit = 0
|
||||
*/
|
||||
template<uint value_size>
|
||||
uint UInt<value_size>::SetBitInWord(uint value, uint bit)
|
||||
uint UInt<value_size>::SetBitInWord(uint & value, uint bit)
|
||||
{
|
||||
TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
|
||||
|
||||
uint old_bit;
|
||||
uint v = value;
|
||||
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||
#endif
|
||||
|
@ -864,15 +875,20 @@ namespace ttmath
|
|||
#ifdef __GNUC__
|
||||
__asm__ __volatile__(
|
||||
|
||||
"btsq %%rbx,%%rax \n"
|
||||
"btsq %%rbx, %%rax \n"
|
||||
|
||||
: "=a" (value)
|
||||
: "0" (value), "b" (bit)
|
||||
"setc %%bl \n"
|
||||
"movzx %%bl, %%rbx \n"
|
||||
|
||||
: "=a" (v), "=b" (old_bit)
|
||||
: "0" (v), "1" (bit)
|
||||
: "cc" );
|
||||
|
||||
#endif
|
||||
|
||||
return value;
|
||||
value = v;
|
||||
|
||||
return old_bit;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue