Somma in C

bad.alex
Ciao ragazzi.
Avrei un dubbio riguardo una sommatoria in C.
Dovrei scrivere la seguente formula:

$S=(1/200)*(\sum|P(t)-C|)$

Avevo pensato di scrivere:

double P[TIME], C, sum;
int t;
sum=0.;
for(t=1; t<200; t++){
sum=(1/200)*(sum+fabs(P[t]-C));
}

printf("Sum: %lf\n", sum); 

 


E' corretto?

Vi ringrazio per l'aiuto

p.s. gli estremi della sommatoria sono 1 e 200.

Risposte
apatriarca
No. (1/200) esegue una operazione intera. Sono infatti due costanti intere e la loro divisione e quindi quella tra numeri interi. Il risultato è quindi zero. Puoi seguire due strategie:
1. Scrivere (1.0 / 200.0).
2. Dividere semplicemente la somma per 200 al di fuori del ciclo una singola volta.

insideworld
nel for dovresti scrivere t<=200 altrimenti sommi solo fino al 199esimo elemento.
se stai scandendo un vettore con 200 elementi allora probabilmente dovresti scrivere for(t=0;t<200,t++)
a questo punto sarebbe giusto fermarsi alla casella numero 199 perchè contando da zero è la 200esima.
inoltre dentro il ciclo for dovresti scrivere
sum=sum+fabs(P[t]-C));

volendo puoi riscriverla usando questo operatore per non ripetere sum
sum += fabs(P[t]-C));
ma se non l'hai mai usato lascia perdere.
infine devi fare la divisione fuori dal ciclo come hanno già detto
sum=sum/200.0

Raptorista1
"apatriarca":
Puoi seguire due strategie:
1. Scrivere (1.0 / 200.0).

Questa non mi sembra corretta. Per come è scritto, la moltiplicazione deve stare per forza fuori dal ciclo [inline]for[/inline].

apatriarca
Avevo letto velocemente il codice e notato subito quell'errore, ma non ho letto il resto. Ovviamente va cambiata la riga in modo da accumulare il risultato al di fuori della moltiplicazione. Fare il prodotto fuori ha diversi vantaggi, ma le soluzioni discusse volevano essere 'generiche'. Ci sono casi in cui un coefficiente non è facile da estrarre ed è necessario assicurarsi che il rapporto sia calcolato con valori in virgola mobile e non interi.

Raptorista1
Sì, capisco. La sommatoria è scritta male in partenza.

kobeilprofeta
1.0/200.0 non è necessario
penso che il .0 basti in uno dei due a tua scelta

Ma sono comunque dettagli

apatriarca
Ne basta uno, ma sono solo due caratteri e preferisco essere esplicito sul tipo delle costanti.

bad.alex
Grazie a tutti per l'aiuto.


(scusate se rispondo in ritardo, ma ho avuto problemi con la connessione)

insideworld
in realtà la somma può stare anche dentro il ciclo però non come l'hai scritta tu @bad.alex
sum=sum + fabs(P[t]-C)/200.0 

in questa maniera dividi ogni elemento della somma prima di sommarlo(propr.distributiva), nell'altra dividevi più volte il risultato delle somme degli elementi precedenti :smt023

kobeilprofeta
Ripetere una divisione n volte in un ciclo quando puoi farla 1 volta fuori è stupido

insideworld
"kobeilprofeta":
Ripetere una divisione n volte in un ciclo quando puoi farla 1 volta fuori è stupido

Certo che è stupido ed è anche meno efficiente (soprattutto considerando la complessità di una divisione per una CPU), ma non è concettualmente sbagliato, e visto che si può fare ho trovato utile spiegare perchè il codice di partenza era sbagliato, ovvero non solo perchè poco efficiente, ma perchè concettualmente si doveva dividere ogni elemento e non la "somma parziale".
L'ho voluto precisare perchè sia io che un altro utente abbiamo scritto che era sbagliato fare la divisione dentro il ciclo, mentre invece è "solo" sconveniente.
sicuramente dividere fuori dal ciclo è più semplice ed è anche "suggerito" dal modo in cui è scritta la sommatoria, ovvero col fattore comune $1/200$ già raccolto, e dovendo scegliere farei così :-D
Saluti

kobeilprofeta
Magari è passato il messaggio sbagliato, scusa :)

Non volevo dare dello stupido a te (ci mancherebbe), né ho pensato che tu la consigliassi come soluzione intelligente. Ho solo precisato affinché l'autore del topic abbia chiaro il concetto.

bad.alex
Vi ringrazio per l'aiuto, ancor più per le spiegazioni. Ho imparato tanto da questo topic ;)

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.