Newsgroup: it.comp.lang.c
Titolo: Funzione str-double

Salve a tutti. Ho un piccolo problema con una funzione (scritta per
esercizio) che converta una stringa in un intero... L'errore sara'
sicuramente una stupidaggine (sono alle prime armi...), ma proprio non
riesco a scovarlo :(
Allora, la funzione riceve il puntatore alla stringa e la lunghezza della
stringa stessa...
double str2double(char *str, int lunghezza)
{
        double num=0;
        int i;
        for (i=0; i<lunghezza; i++) {
                if(isalnum(str[i])) {
                        num=num+(str[i]-'0')*pow(10, i+1);
                }
        }
        return num;
}
Grazie in anticipo :)
-- 
*** Gottardi Matteo / 
goma...@tin.it
 ***
*Linux*, the choice of a _GNU_ generation

}
Questa funzionerebbe se noi scrivessimo i numeri in
modo "little endian"... con le cifre meno significative
"prima", ovvero "a sinistra".  Infatti, esamina il loop: tu
consideri gradualmente PIU' significative le cifre, usando
una potenza di 10 sempre maggiore, man mano che
procedi.  Quindi, supponi ad esempio che la stringa sia
    789
tu la interpreti come il polinomio
    7*pow(10,1) + 8*pow(10,2) + 9*pow(10,3)
ma questo e' un numero che invece noi normalmente
scriviamo come
    9870
mentre il polinomio implicito in "789" e' invece
    7*pow(10,2) + 8*pow(10,1) + 9*pow(10,0)
Volendo dunque mantenere la (costosa!!!-) logica
basata su pow, vedi che il secondo argomento da
passare a pow NON e' i+1, bensi` lunghezza-i+1.
Inoltre, isalnum() e' un test decisamente poco
appropriato -- usa almeno isdigit(), cosi' se ci sono
delle non-cifre le tratti come la cifra '0', invece che
far "sballare" tutto il calcolo.
La principale ottimizzazione che puoi apportare
consiste nell'eliminare l'esplicita chiamata a pow(),
che tende ad essere molto costosa, tenendo
invece calcolata la "potenza corrente" ad ogni
passo del ciclo -- questo puoi farlo con una
semplice moltiplicazione, assai piu` economica.
Il corpo del ciclo diventa cosi`:
    num = num * 10;
    if(isdigit(str[i]))
        num = num + str[i]-'0';
Questo, in pratica, significa calcolare il polinomio
col metodo di Horner, che infatti e' sempre il modo
piu` efficiente di calcolare polinomi.
Alex

Matteo Gottardi (
goma...@tin.it
) wrote:
: Salve a tutti. Ho un piccolo problema con una funzione (scritta per
: esercizio) che converta una stringa in un intero... L'errore sara'
: sicuramente una stupidaggine (sono alle prime armi...), ma proprio non
: riesco a scovarlo :(
: Allora, la funzione riceve il puntatore alla stringa e la lunghezza della
: stringa stessa...
: double str2double(char *str, int lunghezza)
: {
:         double num=0;
:         int i;
:         for (i=0; i<lunghezza; i++) {
:                 if(isalnum(str[i])) {
:                         num=num+(str[i]-'0')*pow(10, i+1);
Io qui metterei
 
	num+=(str[i]-'0')*pow(10, lunghezza-1-i);
Comunque ricordati di inserire 
#include <math.h>
Ma che errore ti da' ?
Ciao ciao
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)

 che tende ad essere molto costosa, tenendo
[....]
Grazie per la risposta. Ho capito l'errore, e anche che devo smetterla
pensare in maniera matematica, ed iniziare a pensare in C :)
