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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -61,6 +61,51 @@ int main()
|
||||||
using namespace ttmath;
|
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();
|
test_uint();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -572,13 +572,6 @@ public:
|
||||||
// (2) moving 'exp_offset' times
|
// (2) moving 'exp_offset' times
|
||||||
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
|
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() )
|
if( IsSign() == ss2.IsSign() )
|
||||||
|
@ -594,8 +587,8 @@ public:
|
||||||
{
|
{
|
||||||
// values have different signs
|
// values have different signs
|
||||||
// there shouldn't be a carry here because
|
// there shouldn't be a carry here because
|
||||||
// (1) (2) and (3) guarantee that the mantissa of this
|
// (1) (2) guarantee that the mantissa of this
|
||||||
// is greater than the mantissa of the ss2
|
// is greater than or equal to the mantissa of the ss2
|
||||||
uint c_temp = mantissa.Sub(ss2.mantissa);
|
uint c_temp = mantissa.Sub(ss2.mantissa);
|
||||||
|
|
||||||
TTMATH_ASSERT( c_temp == 0 )
|
TTMATH_ASSERT( c_temp == 0 )
|
||||||
|
@ -653,7 +646,7 @@ public:
|
||||||
|
|
||||||
if( exp_offset >= mantissa_size_in_bits )
|
if( exp_offset >= mantissa_size_in_bits )
|
||||||
{
|
{
|
||||||
// the second value is too short
|
// the second value is too small
|
||||||
SetZero();
|
SetZero();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -700,7 +693,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if( exp_offset >= mantissa_size_in_bits )
|
if( exp_offset >= mantissa_size_in_bits )
|
||||||
// the second value is too short
|
// the second value is too small
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
||||||
|
@ -745,7 +738,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
if( exp_offset >= mantissa_size_in_bits )
|
if( exp_offset >= mantissa_size_in_bits )
|
||||||
// the second value is too short
|
// the second value is too small
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
||||||
|
@ -966,18 +959,23 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
power this = this ^ pow
|
power this = this ^ pow
|
||||||
pow without a sign
|
(pow without a sign)
|
||||||
|
|
||||||
binary algorithm (r-to-l)
|
binary algorithm (r-to-l)
|
||||||
|
|
||||||
|
return values:
|
||||||
|
0 - ok
|
||||||
|
1 - carry
|
||||||
|
2 - incorrect arguments (0^0)
|
||||||
*/
|
*/
|
||||||
template<uint pow_size>
|
template<uint pow_size>
|
||||||
uint PowUInt(UInt<pow_size> pow)
|
uint Pow(UInt<pow_size> pow)
|
||||||
{
|
{
|
||||||
if(pow.IsZero() && IsZero())
|
if(pow.IsZero() && IsZero())
|
||||||
// we don't define zero^zero
|
// 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;
|
Big<exp, man> result;
|
||||||
result.SetOne();
|
result.SetOne();
|
||||||
|
|
||||||
|
@ -987,7 +985,8 @@ public:
|
||||||
if( result.Mul(start) )
|
if( result.Mul(start) )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if( start.Mul(start) )
|
start_temp = start;
|
||||||
|
if( start.Mul(start_temp) )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
pow.Rcr(1);
|
pow.Rcr(1);
|
||||||
|
@ -1001,27 +1000,31 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
power this = this ^ pow
|
power this = this ^ pow
|
||||||
p can be with a sign
|
|
||||||
p can be negative
|
p can be negative
|
||||||
|
|
||||||
|
return values:
|
||||||
|
0 - ok
|
||||||
|
1 - carry
|
||||||
|
2 - incorrect arguments 0^0 or 0^(-something)
|
||||||
*/
|
*/
|
||||||
template<uint pow_size>
|
template<uint pow_size>
|
||||||
uint PowInt(Int<pow_size> pow)
|
uint Pow(Int<pow_size> pow)
|
||||||
{
|
{
|
||||||
if( !pow.IsSign() )
|
if( !pow.IsSign() )
|
||||||
return PowUInt(pow);
|
return Pow( UInt<pow_size>(pow) );
|
||||||
|
|
||||||
|
|
||||||
if( IsZero() )
|
if( IsZero() )
|
||||||
// if 'p' is negative then
|
// if 'p' is negative then
|
||||||
// 'this' must be different from zero
|
// 'this' must be different from zero
|
||||||
return 1;
|
return 2;
|
||||||
|
|
||||||
if( pow.ChangeSign() )
|
if( pow.ChangeSign() )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
Big<exp, man> t(*this);
|
Big<exp, man> t(*this);
|
||||||
if( t.PowUInt(pow) )
|
uint c_temp = t.Pow( UInt<pow_size>(pow) );
|
||||||
return 1;
|
if( c_temp > 0 )
|
||||||
|
return c_temp;
|
||||||
|
|
||||||
SetOne();
|
SetOne();
|
||||||
if( Div(t) )
|
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) )
|
if( exponent>sint(0) || exponent<=-sint(man*TTMATH_BITS_PER_UINT) )
|
||||||
return false;
|
return 0;
|
||||||
|
|
||||||
sint exp_int = exponent.ToInt();
|
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;
|
exp_int = -exp_int;
|
||||||
|
|
||||||
// !!! here we'll use a new method (method for testing a bit)
|
return mantissa.GetBit(exp_int);
|
||||||
uint value = mantissa.table[ exp_int / TTMATH_BITS_PER_UINT ];
|
|
||||||
value >>= (uint(exp_int) % TTMATH_BITS_PER_UINT);
|
|
||||||
|
|
||||||
return bool(value & 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
power this = this ^ abs([pow])
|
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() )
|
if( pow.IsZero() && IsZero() )
|
||||||
return 1;
|
return 2;
|
||||||
|
|
||||||
if( pow.IsSign() )
|
if( pow.IsSign() )
|
||||||
pow.Abs();
|
pow.Abs();
|
||||||
|
@ -1070,7 +1080,7 @@ public:
|
||||||
|
|
||||||
e_one.SetOne();
|
e_one.SetOne();
|
||||||
one.SetOne();
|
one.SetOne();
|
||||||
result.SetOne();
|
result = one;
|
||||||
|
|
||||||
while( pow >= one )
|
while( pow >= one )
|
||||||
{
|
{
|
||||||
|
@ -1093,24 +1103,30 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
power this = this ^ [pow]
|
power this = this ^ [pow]
|
||||||
pow without a fraction
|
pow is treated as a value without a fraction
|
||||||
pow can be negative
|
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 )
|
TTMATH_REFERENCE_ASSERT( pow )
|
||||||
|
|
||||||
if( !pow.IsSign() )
|
if( !pow.IsSign() )
|
||||||
return PowBUInt(pow);
|
return PowUInt(pow);
|
||||||
|
|
||||||
if( IsZero() )
|
if( IsZero() )
|
||||||
// if 'pow' is negative then
|
// if 'pow' is negative then
|
||||||
// 'this' must be different from zero
|
// 'this' must be different from zero
|
||||||
return 1;
|
return 2;
|
||||||
|
|
||||||
Big<exp, man> temp(*this);
|
Big<exp, man> temp(*this);
|
||||||
if( temp.PowBUInt(pow) )
|
uint c_temp = temp.PowUInt(pow);
|
||||||
return 1;
|
if( c_temp > 0 )
|
||||||
|
return c_temp;
|
||||||
|
|
||||||
SetOne();
|
SetOne();
|
||||||
if( Div(temp) )
|
if( Div(temp) )
|
||||||
|
@ -1122,13 +1138,13 @@ public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
power this = this ^ pow
|
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
|
pow can be negative and with fraction
|
||||||
|
|
||||||
return values:
|
return values:
|
||||||
0 - ok
|
0 - ok
|
||||||
1 - carry
|
1 - carry
|
||||||
2 - incorrect argument ('this')
|
2 - incorrect argument ('this' <= 0)
|
||||||
*/
|
*/
|
||||||
uint PowFrac(const Big<exp, man> & pow)
|
uint PowFrac(const Big<exp, man> & pow)
|
||||||
{
|
{
|
||||||
|
@ -1147,6 +1163,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
power this = this ^ pow
|
power this = this ^ pow
|
||||||
pow can be negative and with fraction
|
pow can be negative and with fraction
|
||||||
|
@ -1175,7 +1192,7 @@ public:
|
||||||
pow_frac.RemainFraction();
|
pow_frac.RemainFraction();
|
||||||
|
|
||||||
if( pow_frac.IsZero() )
|
if( pow_frac.IsZero() )
|
||||||
return PowBInt( pow );
|
return PowInt( pow );
|
||||||
|
|
||||||
// pow is with fraction (not integer)
|
// pow is with fraction (not integer)
|
||||||
// result = e^(pow * ln(this) ) where 'this' must be greater than 0
|
// result = e^(pow * ln(this) ) where 'this' must be greater than 0
|
||||||
|
@ -1318,7 +1335,7 @@ public:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExpSurrounding0(m);
|
ExpSurrounding0(m);
|
||||||
c += PowBUInt(e_);
|
c += PowUInt(e_);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (c==0)? 0 : 1;
|
return (c==0)? 0 : 1;
|
||||||
|
@ -1793,7 +1810,7 @@ public:
|
||||||
// where "1.F" is intended to represent the binary number
|
// where "1.F" is intended to represent the binary number
|
||||||
// created by prefixing F with an implicit leading 1 and a binary point.
|
// 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,
|
e - 1023 - man*TTMATH_BITS_PER_UINT + 1, 0x80000000u,
|
||||||
m1, m2);
|
m1, m2);
|
||||||
|
|
||||||
|
@ -1815,7 +1832,7 @@ public:
|
||||||
m.table[0] = m2;
|
m.table[0] = m2;
|
||||||
uint moved = m.CompensationToLeft();
|
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,
|
e - 1022 - man*TTMATH_BITS_PER_UINT + 1 - moved, 0,
|
||||||
m.table[1], m.table[2]);
|
m.table[1], m.table[2]);
|
||||||
}
|
}
|
||||||
|
@ -1906,7 +1923,7 @@ public:
|
||||||
// where "1.F" is intended to represent the binary number
|
// where "1.F" is intended to represent the binary number
|
||||||
// created by prefixing F with an implicit leading 1 and a binary point.
|
// 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,
|
e - 1023 - man*TTMATH_BITS_PER_UINT + 1,
|
||||||
0x8000000000000000ul, m);
|
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
|
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
|
#ifdef TTMATH_PLATFORM64
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@ -3324,7 +3361,7 @@ private:
|
||||||
new_exponent.ChangeSign();
|
new_exponent.ChangeSign();
|
||||||
|
|
||||||
temp = 10;
|
temp = 10;
|
||||||
c += temp.PowBInt( new_exponent );
|
c += temp.PowInt( new_exponent );
|
||||||
c += Mul(temp);
|
c += Mul(temp);
|
||||||
|
|
||||||
return (c==0)? 0 : 1;
|
return (c==0)? 0 : 1;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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_MAJOR_VER 0
|
||||||
#define TTMATH_MINOR_VER 8
|
#define TTMATH_MINOR_VER 8
|
||||||
#define TTMATH_REVISION_VER 2
|
#define TTMATH_REVISION_VER 3
|
||||||
#define TTMATH_PRERELEASE_VER 0
|
#define TTMATH_PRERELEASE_VER 1
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2008, Tomasz Sowa
|
* Copyright (c) 2006-2009, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -950,9 +950,6 @@ private:
|
||||||
*/
|
*/
|
||||||
uint Rcl2(uint bits, uint c)
|
uint Rcl2(uint bits, uint c)
|
||||||
{
|
{
|
||||||
if( bits == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||||
|
|
||||||
register sint b = value_size;
|
register sint b = value_size;
|
||||||
|
@ -1078,9 +1075,6 @@ private:
|
||||||
*/
|
*/
|
||||||
uint Rcr2(uint bits, uint c)
|
uint Rcr2(uint bits, uint c)
|
||||||
{
|
{
|
||||||
if( bits == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||||
|
|
||||||
register sint b = value_size;
|
register sint b = value_size;
|
||||||
|
@ -1503,30 +1497,40 @@ public:
|
||||||
|
|
||||||
#ifdef TTMATH_PLATFORM32
|
#ifdef TTMATH_PLATFORM32
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets a special bit in the 'value'
|
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>
|
bit is from <0,31>
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
SetBitInWord(0,0) = 1
|
uint x = 100;
|
||||||
SetBitInWord(0,2) = 4
|
uint bit = SetBitInWord(x, 3);
|
||||||
SetBitInWord(10, 8) = 266
|
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 )
|
TTMATH_ASSERT( bit < TTMATH_BITS_PER_UINT )
|
||||||
|
|
||||||
|
uint old_bit;
|
||||||
|
uint v = value;
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
push ebx
|
push ebx
|
||||||
push eax
|
push eax
|
||||||
mov eax, [value]
|
|
||||||
|
mov eax, [v]
|
||||||
mov ebx, [bit]
|
mov ebx, [bit]
|
||||||
bts eax, ebx
|
bts eax, ebx
|
||||||
mov [value], eax
|
mov [v], eax
|
||||||
|
|
||||||
|
setc bl
|
||||||
|
movzx ebx, bl
|
||||||
|
mov [old_bit], ebx
|
||||||
|
|
||||||
pop eax
|
pop eax
|
||||||
pop ebx
|
pop ebx
|
||||||
}
|
}
|
||||||
|
@ -1536,15 +1540,20 @@ public:
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"btsl %2,%0 \n"
|
"btsl %%ebx, %%eax \n"
|
||||||
|
|
||||||
: "=R" (value)
|
"setc %%bl \n"
|
||||||
: "0" (value), "R" (bit)
|
"movzx %%bl, %%ebx \n"
|
||||||
|
|
||||||
|
: "=a" (v), "=b" (old_bit)
|
||||||
|
: "0" (v), "1" (bit)
|
||||||
: "cc" );
|
: "cc" );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return value;
|
value = v;
|
||||||
|
|
||||||
|
return old_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1555,15 +1564,33 @@ public:
|
||||||
|
|
||||||
bit_index bigger or equal zero
|
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;
|
uint index = bit_index / TTMATH_BITS_PER_UINT;
|
||||||
if( index >= value_size )
|
uint bit = bit_index % TTMATH_BITS_PER_UINT;
|
||||||
return;
|
|
||||||
|
|
||||||
bit_index %= TTMATH_BITS_PER_UINT;
|
uint temp = table[index];
|
||||||
|
|
||||||
table[index] = SetBitInWord(table[index], bit_index);
|
return SetBitInWord(temp, bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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:
|
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
|
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 Sub(const UInt<value_size> & ss2, uint c=0);
|
||||||
uint SubInt(uint value, uint index = 0);
|
uint SubInt(uint value, uint index = 0);
|
||||||
static sint FindLeadingBitInWord(uint x);
|
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 MulTwoWords(uint a, uint b, uint * result2, uint * result1);
|
||||||
static void DivTwoWords(uint a,uint b, uint c, uint * r, uint * rest);
|
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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -210,11 +210,13 @@ namespace ttmath
|
||||||
register uint * p2 = const_cast<uint*>(ss2.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__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
/*
|
/*
|
||||||
this part should be compiled with gcc
|
this part should be compiled with gcc
|
||||||
|
@ -281,6 +283,8 @@ namespace ttmath
|
||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
register uint c;
|
register uint c;
|
||||||
|
|
||||||
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
@ -361,6 +365,8 @@ namespace ttmath
|
||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
register uint c;
|
register uint c;
|
||||||
|
|
||||||
|
TTMATH_ASSERT( index < value_size - 1 )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
@ -424,6 +430,9 @@ namespace ttmath
|
||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
register uint * p2 = const_cast<uint*>(ss2.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__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
@ -489,6 +498,8 @@ namespace ttmath
|
||||||
register uint * p1 = table;
|
register uint * p1 = table;
|
||||||
register uint c;
|
register uint c;
|
||||||
|
|
||||||
|
TTMATH_ASSERT( index < value_size )
|
||||||
|
|
||||||
#ifndef __GNUC__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
@ -559,8 +570,8 @@ namespace ttmath
|
||||||
"push %%rdx \n"
|
"push %%rdx \n"
|
||||||
"push %%rcx \n"
|
"push %%rcx \n"
|
||||||
|
|
||||||
"xorq %%rdx, %%rdx \n" // edx=0
|
"xorq %%rdx, %%rdx \n" // rdx=0
|
||||||
"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"
|
"1: \n"
|
||||||
"rclq $1, (%%rbx, %%rdx, 8) \n"
|
"rclq $1, (%%rbx, %%rdx, 8) \n"
|
||||||
|
@ -616,7 +627,7 @@ namespace ttmath
|
||||||
|
|
||||||
"push %%rcx \n"
|
"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"
|
"1: \n"
|
||||||
"rcrq $1, -8(%%rbx, %%rcx, 8) \n"
|
"rcrq $1, -8(%%rbx, %%rcx, 8) \n"
|
||||||
|
@ -658,9 +669,6 @@ namespace ttmath
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::Rcl2(uint bits, uint c)
|
uint UInt<value_size>::Rcl2(uint bits, uint c)
|
||||||
{
|
{
|
||||||
if( bits == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||||
|
|
||||||
register sint b = value_size;
|
register sint b = value_size;
|
||||||
|
@ -739,9 +747,6 @@ namespace ttmath
|
||||||
template<uint value_size>
|
template<uint value_size>
|
||||||
uint UInt<value_size>::Rcr2(uint bits, uint c)
|
uint UInt<value_size>::Rcr2(uint bits, uint c)
|
||||||
{
|
{
|
||||||
if( bits == 0 )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
TTMATH_ASSERT( bits>0 && bits<TTMATH_BITS_PER_UINT )
|
||||||
|
|
||||||
register sint b = value_size;
|
register sint b = value_size;
|
||||||
|
@ -843,20 +848,26 @@ namespace ttmath
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
this method sets a special bit in the 'value'
|
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***
|
***this method is created only on a 64bit platform***
|
||||||
|
|
||||||
bit is from <0,31>
|
bit is from <0,63>
|
||||||
|
|
||||||
e.g.
|
e.g.
|
||||||
SetBitInWord(0,0) = 1
|
uint x = 100;
|
||||||
SetBitInWord(0,2) = 4
|
uint bit = SetBitInWord(x, 3);
|
||||||
SetBitInWord(10, 8) = 266
|
now: x = 108 and bit = 0
|
||||||
*/
|
*/
|
||||||
template<uint value_size>
|
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__
|
#ifndef __GNUC__
|
||||||
#error "another compiler than GCC is currently not supported in 64bit mode"
|
#error "another compiler than GCC is currently not supported in 64bit mode"
|
||||||
#endif
|
#endif
|
||||||
|
@ -864,15 +875,20 @@ namespace ttmath
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
|
|
||||||
"btsq %%rbx,%%rax \n"
|
"btsq %%rbx, %%rax \n"
|
||||||
|
|
||||||
: "=a" (value)
|
"setc %%bl \n"
|
||||||
: "0" (value), "b" (bit)
|
"movzx %%bl, %%rbx \n"
|
||||||
|
|
||||||
|
: "=a" (v), "=b" (old_bit)
|
||||||
|
: "0" (v), "1" (bit)
|
||||||
: "cc" );
|
: "cc" );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return value;
|
value = v;
|
||||||
|
|
||||||
|
return old_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue