Newsgroup: it.comp.lang.c
Titolo: problema con ciclo infinito

salve,
sto cercando di risolvere un'esercizio in C, ma sono alle prese con un
fatto che mi lascia alliibito.
il problema e' il seguente: determinare, senza fare uso della costante
di eulero, il piu' piccolo numero n tale che 1+1/2+1/3+...+1/n >= m,
dove m e' un intero dato.
la soluzione ovvia e'
...
while(temp <= m)
  {
     temp = temp + 1/n;
     n++;
  }
...
e infatti funziona tranquillamente, ma per m non superiore a 15!!!
per m=16, n dev'essere quasi 5000000, mentre il programma non si ferma
mai ed ho constatato che anche dopo un'ora di calcolo non si ferma (con
n che supera 8000000 e quindi temp supera abbondantemente m...).
com'e' possibile che un programma funzioni per certi numeri e per altri
no???
-- 
Misero colui che ignora la fortuna 
di avere a casa un cane che lo aspetta...

 no???
Come hai definito le variabili?
Sono abbastanza capienti?
Ciao
Giuseppe


Il problema e' che per n grande 1.0/n aggiunto a
temp lascia temp inalterato, perche' temp
non e' memorizzato con abbastanza precisione.
Prova a definire temp come double:
#include<stdio.h>
double temp=0.0;
int n=1;
int main()
{
 double temp=0.0;
 int n=0;
 while (temp<=16.0)
 {
   n++;
   temp += 1.0/n;
 }
 printf("n = %d\n",n);
 return 0;
}
e vedrai che ti stampa un numero vicino a 5 milioni...
ciao,
g.

 m...). ...  
Calma e gesso.
Il problema sta nella serie armonica che
notoriamente ha una divergenza molto lenta.
Partiamo dalle stime dell'errore:
posto m = sum_(n=1)^/infnty
ln (n + 1) <= m <= 1 + ln (n)
Da queste stime ricaviamo che:
per m = 15  ->  1202604 < n < 3269016
per m = 16  ->  3269017 < n < 8886109
Che non e` affatto in accordo con quanto hai riportato.
Comunque passare dai float ai double non aiuta molto 
(anche se, come ti hanno fatto notare, per calcoli
scientifici si dovrebbero sempre usare i double tranne 
casi particolari)
Ma anche usando i double non risolveresti il probema 
perche` usando le stime per l'errore che ho fornito 
(in verita` un po' grezze):
per n=16 i tempi di calcolo rimangono sempre dell'
ordine di un'ora e mezza o due
per n=17 i tempi di calcolo diventano mezza giornata
per n=20 i tempi di calcolo diventano alcuni giorni
per n=22 stimo una settimana
per n=24 stimo piu' di un mese
Secondo me lamenterai ancora cicli infiniti ;)

 m...). ...  
Calma e gesso.
Il problema sta nella serie armonica che
notoriamente ha una divergenza molto lenta.
Partiamo dalle stime dell'errore:
posto m = sum_(n=1)^/infnty
ln (n + 1) <= m <= 1 + ln (n)
Da queste stime ricaviamo che:
per m = 15  ->  1202604 < n < 3269016
per m = 16  ->  3269017 < n < 8886109
Che non e` affatto in accordo con quanto hai riportato.
Comunque passare dai float ai double non aiuta molto 
(anche se, come ti hanno fatto notare, per calcoli
scientifici si dovrebbero sempre usare i double tranne 
casi particolari) e  non risolveresti il probema;


 ordine di un'ora e mezza o due
mi sembra un po' strana come stima...
il programmino che ho fatto vedere nel messaggio prima
per m = 16 stampa 4989190 e ci mette circa 7 centesimi
di secondo, non una ora e mezzo...
su che hw hai stimato 90 minuti per fare
5 miseri milioni di divisioni e somme in floating point ?
comunque e' chiaro che data la convergenza molto
lenta della serie il metodo naif accumula un
sacco di errore.
ciao,
g.

 g.
innanzitutto grazie mille a tutti e due per l'aiuto!
in effetti il problema era proprio quello, come del resto sospettavo
anche io conoscendo il limite dei float.
avevo provato a usare i double, ma con i double sorgeva un'altro
problema; infatti quel ciclo che ho postato e' dentro un ulteriore ciclo
e usando i double era il ciclo superiore a impazzire...
grazie al tuo esempio ho posto maggiore attenzione ai tipi e ora
funziona tutto!
grazie ancora!
PS: se avessi postato tutto il codice del programma sicuramente sareste
riusciti immediatamente a vedere tutti gli errori, e' che siccome questa
e' un esercitazione valida per il corso di informatica I, ho pensato che
il prof non avrebbe molto gradito che qualcuno postasse su usenet la
soluzione completa di un esercizi di cui e' probabile la discussione
durante l'orale... :-D


 Secondo me lamenterai ancora cicli infiniti ;)
:-D
credevo di avere un computer un po' datato, ma a quanto pare invece va
ancora piu' di un cluster! :-)
per m=16:
          n=4989191
          neulero=4989191.023763
real    0m0.599s
user    0m0.080s
sys     0m0.000s
...
per m=24:
          n=0
          neulero=14872568831.162054
real    1m11.375s
user    1m10.772s
sys     0m0.000s
considerando anche il tempo perso a digitare il valore di m!
:-D


 mi sembra un po' strana come stima...
Si basa sui dati ricavabili dalla domanda;
si diceva che ha fermato le iterazioni dopo piu` 
di un'ora per n=15 (Ok era m=15 ma avevo letto male)
Ho sbagliato tutto.  Mi scuso.
 

 dopo provo a vedere per m = 100 quanto ci mette! :-D
Se usi i double avrai un ciclo infinito.
In effetti i problemi cominceranno per m = 36.

 altre risposte..
ma figurati!
anzi, grazie mille per aver cercato di aiutarmi! 


 anzi, grazie mille per aver cercato di aiutarmi!
Si vede che oggi non e` la mia giornata.


Dovresti leggere "m" dalla riga di comando ;-)
E.

 Dovresti leggere "m" dalla riga di comando ;-)
beh, l'esercizio prevedeva semplicemente lo scanf da tastiera per 
l'immissione di m  :-)