Con le seguenti funzioni è possibile trasformare un numero nella stringa corrispondente. Sono presentate le funzioni _itoa()
, _ltoa()
, _ultoa()
, _ftoa()
per convertire rispettivamente tipi int, long, unsigned long, e float in stringhe. La scelta di anteporre un underscore ( _ ) prima del nome della funzione è reso necessario dal fatto che queste sono automaticamente supportate da alcuni compilatori, quindi se programmate per esempio in Turbo C non c’è bisogno di inserirle nel vostro programma (Consultate le referenze del vostro compilatore per conoscere se sono supportate o meno). L’utilizzo di _itoa(), _ltoa() e _ultoa() è simile in quanto sostanzialmente fanno tutte da wrapper tramite casting alla funzione xtoa()
che esegue il lavoro reale. Per quanto riguarda _ftoa() la chiamata differisce in quanto invece di passare la radice di conversione bisogna passare la precisione dei numeri prima e dopo la virgola.
Entriamo nei dettagli:
I parametri per le funzioni _itoa(), _ltoa() e _ultoa() sono val
(il numero da convertire, rispettivamente di tipo int, long oppure unsigned long. Il buffer precedentemente allocato in cui salvare i risultati, la radice ovvero la base su cui effettuare la conversione (per il decimale è 10, per l’esadecimale 16 per l’ottale 8, ecc…).
Tutte ritornano un puntatore al buffer passato.
static void xtoa (unsigned long val,char *buf,
unsigned radix,int is_neg) {
char *p; /* pointer to traverse string */
char *firstdig; /* pointer to first digit */
char temp; /* temp char */
unsigned digval; /* value of digit */
p = buf;
if (is_neg) {
/* negative, so output '-' and negate */
*p++ = '-';
val = (unsigned long)(-(long)val);
}
firstdig = p; /* save pointer to first digit */
do {
digval = (unsigned) (val % radix);
val /= radix; /* get next digit */
/* convert to ascii and store */
if (digval > 9)
*p++ = (char) (digval - 10 + 'a'); /* a letter */
else
*p++ = (char) (digval + '0'); /* a digit */
} while (val > 0); /* We now have the digit of the number in the buffer,
but in reverse order. Thus we reverse them now. */
*p-- = '\0'; /* terminate string; p points to last digit */
do {
temp = *p;
*p = *firstdig;
*firstdig = temp; /* swap *p and *firstdig */
--p;
++firstdig; /* advance to next two digits */
} while (firstdig < p); /* repeat until halfway */
}
/* Actual functions just call conversion helper with neg
flag set correctly,
and return pointer to buffer. */
char * _itoa (int val,char *buf,int radix) {
if (radix == 10 && val < 0)
xtoa((unsigned long)val, buf, radix, 1);
else
xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
return buf;
}
char * _ltoa (long val,char *buf,int radix) {
xtoa((unsigned long)val, buf, radix, (radix == 10 && val < 0));
return buf;
}
char * _ultoa (unsigned long val,char *buf,int radix) {
xtoa(val, buf, radix, 0);
return buf;
}
Qui invece viene presentata la funzione _ftoa()
che come anticipato prima differisce nei parametri passati; infatti essa richiede come primo argomento il solito val
in formato float ovvero il numero da convertire, come secondo e terzo parametro la precisione da utilizzare nella conversione (Attenzione m
deve essere comunque minore di 15 e n
minore di 12), e a
invece è il buffer dove saranno inseriti i risultati. Notate che la lunghezza di a
sarà proprio uguale a n+m+2. Anch’essa ritorna un puntatore al buffer passato.
#include <math.h>
int _ftoa(float val, int n, int m, char *a)
{
int i, j, b[15], c[15];
char sign= ' ';
double x;
if (n > 15 || m > 12)
return(0);
n = n-m-2;
if (val < 0) {
val = -val;
sign= '-';
}
while (val > pow(10.,(double)n))
++n;
if (n > 15)
return(0);
for (i = n-1; i > 0; --i)
{
x = pow(10.,(double)i);
b[n-1-i] = val/x;
val -= (float)b[n-1-i]*x;
}
b[n-1-i] = val;
val -= (float)b[n-1-i];
val = val * pow(10.,(double)m);
val = (float)(floor(2*val) - (int)val);
for (i=m-1; i > 0; --i) {
x = pow(10.,(double)i);
c[m-1-i] = val / x;
val -= (float)c[m-1-i]*x;
if (c[m-1-i] == 10) {
c[m-1-i] = 0;
for (j=0; n-1-j >= 0; ++j) {
if (++b[n-1-j] < 10)
break;
else b[n-1-j]= 0;
}
if (b[0] == 0) {
++n;
b[0]= 1;
for (j = 1; j < n; ++j)
b[j]=0;
}
}
}
c[m-1-i] = val;
a[0] = sign;
for (i = 0; i < n-1; ++i) {
if (b[i] > 0)
break;
else {
a[1+i] = sign;
a[i] = ' ';
}
}
for ( ; i < n; ++i)
a[1+i] = b[i] + '0';
a[1+i] = '.';
for (i = 0; i < m; ++i)
a[n+2+i] = c[i] + '0';
return a;
}