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;
}
 

Reply via email to