Hi,
I have tried to optimize this function (sprintf using %.*lf format)
int CodeDouble( double aValue, int precision, char* put) {
return sprintf( put, "%.*lf", precision, aValue );
}
After testing it, I considered inefficient.(not so fast)
So, I write this one, longer, but quicker (depending on which
OS/compiler I use).
Do you see improvment I can do to be faster (but still not buggy) or
just clarify some parts
of the code.
I have a full test suite against de sprintf method to valid this code.
there are an assert about decimal and integer part (go into an int and a
long long)
// input : a double, the precision (number of digit after the dot), an
output buffer
// return total bytes written in put
// ----------------------------------------------------
int CodeDoubleEx( double aValue, int precision, char* put)
{
// Some preliminaries
bool isNeg = false;
bool hasDecimale = precision;
if ( aValue < 0 )
{
aValue = -aValue;
*put++ = '-';
isNeg = true;
}
// Backup the beginning for the end reversing
char* bufferBeginning = put;
// Extract the interger part
long long entiere = (long long)aValue;
aValue -= entiere;
// Extract the decimal part
int decimaleMax = 1;
for ( int tmp = precision; tmp > 0; --tmp )
{
aValue *= 10;
decimaleMax *= 10;
}
aValue += 0.5;
int decimale = (int)aValue;
// Do we have an overflow
if ( decimale >= decimaleMax )
{
// increment the integer part and decrement the decimale ones
++entiere;
decimale -= decimaleMax;
}
// Writing decimal part in reverse order
if ( decimale )
{
for ( int tmp = decimale; tmp && precision; tmp /=10 )
{
*put++ = '0' + (char)( tmp % 10 );
--precision;
}
}
// Add some missing '0' before the dot
for ( int tmp = precision; tmp; --tmp )
*put++ = '0';
// Writing dot if necessary
if ( hasDecimale )
*put++ = '.';
// Writing integer part in reverse order
if ( entiere )
{
for ( int tmp = entiere; tmp; tmp /=10 )
{
*put++ = '0' + (char)( tmp % 10 );
}
}
else
*put++ = '0';
// Reverse back what was written
int size = put - bufferBeginning + isNeg - 1;
while( put > bufferBeginning )
{
char c = *--put;
*put = *bufferBeginning;
*bufferBeginning++ = c;
}
return size;
}