Code:
Testing version : Elysia
------------------------------
Testing on AMD Athlon II X2 250 (3 GHz)
OS = Windows 7 Ultimate 64 bit -- Compiler = Microsoft Visual Studio 2010
The value of num is: -1234567890
The formatted value of num is: -1,234,567,890
Elapsed time: 208 ms to perform 10,000,000 cycles
-------------------------------------------------------
handling 0 ---> 0
handling 12 ---> 12
handling 256 ---> 256
handling 1000 --> 1,000
handling 1000000 ---> 1,000,000
handling 1000000000 ---> 1,000,000,000
handling 2147483647 -> 2,147,483,647
handling -2147483648 -> -2,147,483,648
Press any key to continue . . .
Code:
// ----------------------------------------------------------------------------------------------
// Prog_name: testpad.c
// A program for testing functions formatting integer numbers with
// thousand separators and sign.
//-----------------------------------------------------------------------------------------------
// Created with Pelles C for Windows 6.00.4
// Standard ISO C99
//-----------------------------------------------------------------------------------------------
// Date: 09 july 2010
// Testpad by frktons
//-----------------------------------------------------------------------------------------------
#include <stdio.h>
#include <time.h>
#include <string.h>
//-----------------------------------------------------------------------------------------------
// Function prototype for itoa(). Takes in the number to
// format, and the pointer of the buffer to fill. Returns an int.
//-----------------------------------------------------------------------------------------------
void itoa(long num, char []);
char digits_table[999999][8];
//-----------------------------------------------------------------------------------------------
int main(void)
{
for (int i = 0; i < 999999; i++)
{
for (int j = 0; j < 8; j++)
{
digits_table[i][0] = ',';
digits_table[i][1] = '0' + char(i / 100000);
digits_table[i][2] = '0' + char(i / 10000 % 10);
digits_table[i][3] = '0' + char(i / 1000 % 10);
digits_table[i][4] = ',';
digits_table[i][5] = '0' + char(i / 100 % 10);
digits_table[i][6] = '0' + char(i / 10 % 10);
digits_table[i][7] = '0' + char(i % 10);
}
}
long num = -1234567890; // test number
int cycles = 0;
clock_t start = 0; // initial time
clock_t stop = 0; // end time
const char *ver = "Elysia"; // Program version
char buffer[50] = {'\0'}; // string array for the formatted number
// 10 digits max + 3 separators max + sign + NULL
long times = 10000000; // for testing performance set this number for repetitions
//-----------------------------------------------------------------------------------------------
// HW-SW platform
//-----------------------------------------------------------------------------------------------
const char *OS = "Windows 7 Ultimate 64 bit";
const char *CPU = "AMD Athlon II X2 250 (3 GHz)";
const char *compiler = "Microsoft Visual Studio 2010";
//-----------------------------------------------------------------------------------------------
printf("\n\t\t Testing version : %s \n",ver);
printf("\t\t ------------------------------\n");
printf(" Testing on %s\n",CPU);
printf(" OS = %s -- Compiler = %s\n",OS,compiler);
printf("\n The value of num is: %d\n",num);
start = clock();
for (cycles = 0; cycles < times; cycles++) {
itoa(num,buffer);
} // end for
stop = clock();
printf("\n The formatted value of num is: %s\n",buffer);
itoa((long)(stop-start)/(CLOCKS_PER_SEC/1000),buffer);
printf("\n Elapsed time: %s ms",buffer);
itoa(times,buffer);
printf(" to perform %s cycles\n",buffer);
//------------------------------------------------------------------------------
// Test some numbers
//------------------------------------------------------------------------------
printf(" -------------------------------------------------------\n");
long test = -2147483647 - 1;
itoa(0,buffer);
printf("\n handling 0 ---> %s",buffer);
itoa(12,buffer);
printf("\n handling 12 ---> %s",buffer);
itoa(256,buffer);
printf("\n handling 256 ---> %s",buffer);
itoa(1000,buffer);
printf("\n handling 1000 --> %s",buffer);
itoa(1000000,buffer);
printf("\n handling 1000000 ---> %s",buffer);
itoa(1000000000,buffer);
printf("\n handling 1000000000 ---> %s",buffer);
itoa(2147483647,buffer);
printf("\n handling 2147483647 -> %s",buffer);
itoa(test,buffer);
printf("\n handling -2147483648 -> %s\n",buffer);
return 0;
}
//---------------------------------------------------------------
// itoa() - Elysia's version
//---------------------------------------------------------------
__forceinline void itoa(long num, char buffer[])
{
int remain = 0; // integer variable to store the remainder
bool neg = false;
const int sizeof_buffer = 30;
unsigned long newnum;
memset(buffer, 0, 50);
if (num == 0)
{
strcpy(buffer, "0");
return;
}
if (num < 0)
{
neg = true;
buffer[0] = '-';
newnum = -num; // transform number to positive if negative
}
else
newnum = num;
int x, copy_from_offset = 0;
for (x = sizeof_buffer - 1; newnum; x -= 8)
{
if (newnum < 100000)
{
copy_from_offset = 1;
if (newnum < 10) copy_from_offset = 6;
else if (newnum < 100) copy_from_offset = 5;
else if (newnum < 1000) copy_from_offset = 4;
else if (newnum < 10000) copy_from_offset = 2;
}
remain = newnum % 1000000;
newnum /= 1000000;
memcpy(&buffer[x - 8], digits_table[remain], 8);
}
int copy_to = 0;
if (neg) copy_to++;
memmove(&buffer[copy_to], &buffer[x + 1] + copy_from_offset, sizeof_buffer - x - 1 - copy_from_offset);
buffer[sizeof_buffer - x - 1] = '\0';
}
There you go. Quick and dirt. x64 version (beats x86 version by ~2x).