changed: UInt::ToString() had O(n^2) complexity
where n was the number of digits to print now it has O(n) git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@340 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
231164f6ea
commit
e8daa77d75
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
* Copyright (c) 2006-2011, 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
|
||||||
|
@ -1315,13 +1315,11 @@ private:
|
||||||
{
|
{
|
||||||
Int<value_size> temp(*this);
|
Int<value_size> temp(*this);
|
||||||
temp.Abs();
|
temp.Abs();
|
||||||
|
temp.UInt<value_size>::ToStringBase(result, b, true);
|
||||||
temp.UInt<value_size>::ToString(result, b);
|
|
||||||
result.insert(result.begin(), '-');
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UInt<value_size>::ToString(result, b);
|
UInt<value_size>::ToStringBase(result, b, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006-2010, Tomasz Sowa
|
* Copyright (c) 2006-2011, 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
|
||||||
|
@ -3204,36 +3204,96 @@ public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
|
||||||
|
/*!
|
||||||
|
an auxiliary method for converting into the string
|
||||||
|
it returns the log (with the base 2) from x
|
||||||
|
where x is in <2;16>
|
||||||
|
*/
|
||||||
|
double ToStringLog2(uint x) const
|
||||||
|
{
|
||||||
|
static double log_tab[] = {
|
||||||
|
1.000000000000000000,
|
||||||
|
0.630929753571457437,
|
||||||
|
0.500000000000000000,
|
||||||
|
0.430676558073393050,
|
||||||
|
0.386852807234541586,
|
||||||
|
0.356207187108022176,
|
||||||
|
0.333333333333333333,
|
||||||
|
0.315464876785728718,
|
||||||
|
0.301029995663981195,
|
||||||
|
0.289064826317887859,
|
||||||
|
0.278942945651129843,
|
||||||
|
0.270238154427319741,
|
||||||
|
0.262649535037193547,
|
||||||
|
0.255958024809815489,
|
||||||
|
0.250000000000000000
|
||||||
|
};
|
||||||
|
|
||||||
|
if( x<2 || x>16 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return log_tab[x-2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
an auxiliary method for converting to a string
|
an auxiliary method for converting to a string
|
||||||
|
it's used from Int::ToString() too (negative is set true then)
|
||||||
*/
|
*/
|
||||||
template<class string_type>
|
template<class string_type>
|
||||||
void ToStringBase(string_type & result, uint b = 10) const
|
void ToStringBase(string_type & result, uint b = 10, bool negative = false) const
|
||||||
{
|
{
|
||||||
UInt<value_size> temp( *this );
|
UInt<value_size> temp(*this);
|
||||||
|
uint rest, table_id, index, digits;
|
||||||
|
double digits_d;
|
||||||
char character;
|
char character;
|
||||||
uint rem;
|
|
||||||
|
|
||||||
result.clear();
|
result.clear();
|
||||||
|
|
||||||
if( b<2 || b>16 )
|
if( b<2 || b>16 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if( !FindLeadingBit(table_id, index) )
|
||||||
|
{
|
||||||
|
result = '0';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( negative )
|
||||||
|
result = '-';
|
||||||
|
|
||||||
|
digits_d = table_id; // for not making an overflow in uint type
|
||||||
|
digits_d *= TTMATH_BITS_PER_UINT;
|
||||||
|
digits_d += index + 1;
|
||||||
|
digits_d *= ToStringLog2(b);
|
||||||
|
digits = static_cast<uint>(digits_d) + 3; // plus some epsilon
|
||||||
|
|
||||||
|
if( result.capacity() < digits )
|
||||||
|
result.reserve(digits);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
temp.DivInt(b, &rem);
|
temp.DivInt(b, &rest);
|
||||||
character = static_cast<char>( Misc::DigitToChar(rem) );
|
character = static_cast<char>(Misc::DigitToChar(rest));
|
||||||
result.insert(result.begin(), character); // !! it has O(n^2) complexity, change it
|
result.insert(result.end(), character);
|
||||||
// take the one from winix
|
|
||||||
}
|
}
|
||||||
while( !temp.IsZero() );
|
while( !temp.IsZero() );
|
||||||
|
|
||||||
return;
|
size_t i1 = negative ? 1 : 0; // the first is a hyphen (when negative is true)
|
||||||
|
size_t i2 = result.size() - 1;
|
||||||
|
|
||||||
|
for( ; i1 < i2 ; ++i1, --i2 )
|
||||||
|
{
|
||||||
|
char tempc = static_cast<char>(result[i1]);
|
||||||
|
result[i1] = result[i2];
|
||||||
|
result[i2] = tempc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
Loading…
Reference in New Issue