And now we are about half-way: 0.5 version.
I've implemented the suggestions given by some of you
about global and local variables, and replaced the lookup array
with the 'trick of the tale' Elysia pointed to.
The performances are different, but only with CPU cycles
counting I'll be sure about that.
Code:
// ----------------------------------------------------------------------------------------------
// Prog_name: comma_sep.c / ver 0.5
// A routine for formatting integer numbers with thousand separators.
// Created with Pelles C for Windows 6.00.4
//-----------------------------------------------------------------------------------------------
// This version takes into account the sign and the possibility to have different
// separator like space, comma, point, and so on.
// Moveover this version creates a function that can be tested for performance.
// Added the choice for right and left alignment.
// In this version Global variables have been removed.
//-----------------------------------------------------------------------------------------------
// Date: 04 july 2010
// Author: frktons @ cprogramming forum.
//-----------------------------------------------------------------------------------------------
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#undef getchar
#pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
//-----------------------------------------------------------------------------------------------
// Function prototype for int_format(). Takes the number to format,
// the address of the string to fill, some switches and thousand separator.
// Returns nothing.
//-----------------------------------------------------------------------------------------------
void int_format(int num, char *, bool sign, bool neg, char sep, char alignment);
//-----------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
//-----------------------------------------------------------------------------------------------
// Local variables.
//-----------------------------------------------------------------------------------------------
bool sign = true; // if the number has to be displayed with sign
bool neg = false; // if the number is negative this flag will be set
// from the function to reflect the state
char sep = ','; // here I choose the separator
char buffer[15] = {' '}; // string array for the formatted number
char alignment = ' '; // choice to [R]ight-align or [L]eft-align the number
int num = -123456; // test number
int cycles = 0;
int x; // generic integer counter
time_t init_time = 0; // initial time
time_t end_time = 0; // end time
alignment = 'L'; // the formatted number will be Left-aligned
int times = 50000000; // for testing performance set this number for repetitions
printf("\n The value of num is: %d\n",num);
time(&init_time);
printf("\n init_time = %d \n",init_time);
for (cycles = 0; cycles < times; cycles++) {
for (x=0; x < 14; x++)
buffer[x] = ' ';
int_format(num, buffer, sign, neg, sep, alignment);
} // end for
printf("\n The formatted value of num is: ");
for (x = 0; x < 14; x++)
{
if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
printf("%c",buffer[x]);
if (buffer[x] == '\0')
break;
}
printf("\n\n");
time(&end_time);
printf(" end_time = %d \n",end_time);
printf("\n\n The routine test has taken about %d seconds\n", end_time - init_time);
for (x=0; x < 14; x++)
buffer[x] = ' ';
// buffer[14] = '\0';
neg = false;
sign = false;
int_format(times, buffer, sign, neg, sep, alignment);
printf("\n to perform ");
for (x = 0; x < 14; x++)
{
if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
printf("%c",buffer[x]);
if (buffer[x] == '\0')
break;
}
printf(" cycles of the formatting function");
getchar();
return 0;
}
//--------------------------------------------------------------------------------------------------------------------
// Function int_format()
//--------------------------------------------------------------------------------------------------------------------
void int_format(int num, char *buffer, bool sign, bool neg, char sep, char alignment){
int x = 0;
int y = 0;
int remain = 0; // integer variable to store the remainder
int count = 0; // integer counter for positioning the separator
bool zero = false; // if the number is zero the function sets this
// flag for its decisions
// char digit[10] = {'0','1','2','3','4','5','6','7','8','9'}; // the digits to display in char shape
int len_str = 14; // string lenght less the terminator NULL
if (num != 0)
{
if (num < 0)
{
neg = true;
num = num * -1 ; // transform number to positive if negative
}
for (x = len_str; x >= 0; x--)
{
if (num == 0)
break;
if (count == 3)
{
count = 0;
buffer[x] = sep;
x--;
}
remain = num % 10;
num = num / 10;
// buffer[x] = digit[remain];
buffer[x] = '0' + remain;
count++;
}
}
else
{
buffer[len_str] = '0';
zero = true;
}
if (sign == true && neg == true)
buffer[x] = '-';
else if (sign == true && zero == false)
buffer[x] = '+';
if (alignment == 'L') {
if (x == 0)
return;
for (y = 0; y < 15; y++, x++) {
buffer[y] = buffer[x];
if (buffer[y] == '\0')
return;
} // end for
}
return;
}
The performance gap:
Code:
Testing version : 0.40
----------------------
The value of num is: -1234567890
init_time = 1278231197
The formatted value of num is: -1,234,567,890
end_time = 1278231263
The routine test has taken about 66 seconds
to perform 500,000,000 cycles of the formatting function
versus:
Code:
Testing version : 0.50
----------------------
The value of num is: -1234567890
init_time = 1278231354
The formatted value of num is: -1,234,567,890
end_time = 1278231447
The routine test has taken about 93 seconds
to perform 500,000,000 cycles of the formatting function
It looks like version 0.4 is about 35% faster than version 0.5.