Newsgroup: it.comp.lang.c
Titolo: Bug del compilatore?

Salve a tutti!
Ho da poco ricominciato a studiare il C e ho trovato un esercizio per
trovare tutti i numeri primi da 0 a N utilizzando un array di long e
settando a 0 o a 1 i singoli bit dell'array a seconda se il numero fosse o
meno primo... Purtroppo però, in fase di esecuzione (Compilato e linkato con
borland c++ 3.0), mi dice: Floating point error:Divide by 0. Come è
possibile se non c'è alcuna divisione x 0? e cosa ancora più strana, come
mai il programma funziona se prima della riga:
temp=(x/32.0)
metto:
printf("");            ??
Che sia un difetto del compilatore? Vi è mai successa una cosa del genere?!?
Ho provato ad usare il gcc ma mi sono accorto di avere l'unica distribuzione
linux d'Italia che non lo includeva da nessuna parte (accidenti alle riviste
che ti regalano linux!) e quello per dos non vuole assolutamente funzionare!
Sotto posto il codice...
Grazie a tutti x l'aiuto!
P.S. L'algoritmo non è un granché elegante ma DEVE funzionare...
/*Crivello di Erastotene
#include <stdio.h>
#define FLOATVAL 100
#define MAXVAL 3200
unsigned long nprimi[FLOATVAL];
unsigned long maschera[31];
void InitMask(void)
{
 maschera[0]=1;
 for (int x=1;x<=31;x++)
  maschera[x]=maschera[x-1]<<1;
 return;
}
void segnabit(int x)
{
 /* Qui calcolo l'indice reale in base all'indice assoluto... */
 int indice,bit;
/* SE NON METTO QUESTO printf(""); ALLA RIGA SUCCESSIVA MI DICE DIV BY 0 !!
*/
 printf("");
 float temp;
 temp=(x/32.0);  // <<<<<<<<<<<<------------------------------------    DIV
BY 0
 indice=(int)temp;
 bit=(int)((temp-indice)*32);
 nprimi[indice]=((nprimi[indice]) | (maschera[bit]));
 return;
}
void main(void)
{
 InitMask();
 int n,i,x;
 int indice,bit;
 do {
  printf("\nImmetti il numero massimo: ");
  scanf("%d",&n);
 } while (n>MAXVAL);
 /* questo while e questo for trovano i numeri che non sono primi
    col metodo di erastotene... */
 i=2;
 while (i<n) {
  for (x=(i*2);x<=n;x+=i) {
   segnabit(x);
  }
  i++;
 }
 // Qui FINALMENTE scrivo i numeri primi (se mi riesce...);
 printf("\nEccoli qua! Questi sono tutti numeri primi da 0 a %d:\n",n);
 for (i=0;i<=n;i++) {
  float temp;
  temp=(i/32.0);
  indice=(int)temp;
  bit=(int)((temp-indice)*32);
  if (!(nprimi[indice] & maschera[bit])) {
   printf("\t %d",i);
  }
 }
 return;
}

 void main(void)
fai tornare un int, non un void (vedi post precedenti).
Compilandolo con gcc e correggendo quei due particolati, a me funziona

 Compilandolo con gcc e correggendo quei due particolati, a me funziona
O meglio: viene compilato correttamente e viene eseguito senza errori di
division by 0.

 ha scritto nel messaggio
news:iO32c.5673$Hl1....@tornado.fastwebnet.it...

Ok, grazie adesso provo... X quanto riguarda il void main e le dichiarazioni
di int dentro ai cicli è colpa del mio studio da autodidatta!
Probabilmente quel div by 0 è colpa del borland, non è la prima volta che mi
fa questi scherzetti...

 C99. Dichiarala fuori, come variabile locale.
Eh? Sei sicuro? A me sembrava che semplicemente avessero cambiato l'area di
visibilità (lo scope) delle variabili dichiarate in questa maniera
(saranno/sono visibili solo all'interno del blocco in cui sono state
dichiarate, per cui solo all'interno del ciclo for)
--- bye

Mi spiegheresti come funziona il tuo programma? Io ho cercato di
comprenderlo... Ma devo ammettere che la sua logica mi sfugge...
Sei sicuro di dover passare attraverso i floating points? Probabilmente
potresti usare il modulo di divisioni intere per ottenere il numero che
cerchi. Il VS.Net non mi dà errori. Si lamenta solo che 32.0 è un double che
poi viene castato a float (E il tutto sembra funzionare). Occhio che 0 non è
primo!
--- bye

 dichiarate, per cui solo all'interno del ciclo for)
Mmmm mi hai fatto venire dei dubbi! Ho cercato su google ma non ho trovato
niente.
Ad ogni modo se provo a compilare codice con una sintassi di quel tipo, il
compilatore mi segnala un errore.

 compilatore mi segnala un errore.
Guarda questo:
http://groups.google.com/groups?hl=it&lr=&ie=UTF-8&oe=UTF-8&threadm=3DF60FE9.F8BAC83C%40saicmodis.com&rnum=1&prev=/groups%3Fhl%3Dit%26lr%3D%26ie%3DUTF-8
%26oe%3DUTF-8%26q%3D6.8.5.3%2Bc99



Nello standard c'e' scritto:
6.8.5.3 The for statement
1 
The statement
for ( clause-1 ; expression-2 ; expression-3 ) statement
behaves as follows: The expression expression-2 is the controlling
expression that is evaluated before each execution of the loop body.
The expression expression-3 is evaluated as a void expression after
each execution of the loop body. If clause-1 is a declaration, the
scope of any variables it declares is the remainder of the declaration
and the entire loop, including the other two expressions; it is
reached in the order of execution before the first evaluation of the
controlling expression. If clause-1 is an expression, it is evaluated
as a void expression before the first evaluation of the controlling
expression.133) 
2
Both clause-1 and expression-3 can be omitted. An omitted expression-2
is replaced by a nonzero constant.
Quindi, dato che e' previsto che clause-1 sia una dichiarazione, direi
che for(int i = 0; /*...*/) sia corretto... Ma forse negli standard
vecchi non lo era, anche perche' io sapevo che non lo fosse...
Piu' di cosi', non so!
Ciao,
Zeppe

compilatore mi segnala un errore.
   Pero` in C99 si puo`:
6.8.5.3 The for statement
The statement
   for ( clause-1 ; expression-2 ; expression-3 ) statement
[...] If clause-1 is a declaration, the scope of any variables it
declares is the remainder of the declaration and the entire loop,
including the other two expressions; it is reached in the order of
execution before the first evaluation of the controlling expression. 
-- 
S.L.

 vecchi non lo era, anche perche' io sapevo che non lo fosse...
Strano! Io ho studiato sul primo ansi C, e mi pareva si potesse... Boh?

  --- bye
Ciao

Strano! Io ho studiato sul primo ansi C, e mi pareva si potesse... Boh?
Avrei detto: "Possibilissimo", perche' non ne ero affatto sicuro, ma
questo e' quello che mi dice il gcc 3.2, quando dichiaro dentro il
for:
`for' loop initial declaration used outside C99 mode
Mi sembra che non lasci spazio a dubbi! :)
Ciao,
Zeppe

 Strano! Io ho studiato sul primo ansi C, e mi pareva si potesse... Boh?
No, si  poteva con i compilatori  MS, che avevano anche  delle regole di
scope molto  strane... La variabile /i/ dell'esempio  diventava visibile
da quel punto  del programma in poi. Con le recenti  versione la cosa e`
stata sistemata.
Cmq la feature e` stata inserita nel C99 e proviene dal C++.
Luca
-- 
Home: 
http://kronoz.cjb.net
42

 Mi sembra che non lasci spazio a dubbi! :)
prova con -std=c99 o -std=gnu99
Casomai stà dicendo il contrario... non "outside the loop" ma "outside
C99 mode".
Il default credo che sia c98 dove appunto ci sono problemi.

Il default credo che sia c98 dove appunto ci sono problemi.
yep. Infatti non volevo fare una dichiarazione dentro un for, ma dire
a Kernel Panic che, nonstante io avessi avuto dei dubbi sul fatto che
la dichiarazione con il vecchio standard non fosse ammessa, il gcc mi
dava ragione (cioe', non era proprio ammessa)!
Ciao,
Zeppe



Ho il cervello in pausa pranzo... col C e l'inglese funziona ancora.
L'italiano ancora deve arrivare al caffe :(
Comunque a parte reciproci fraintendimenti:
- nel c99 si possono dichiarare variabili all'interno di un ciclo for
e lo scope è il ciclo for
- il gcc almeno per questa faccenda aderisce allo standard
signed, sealed and delivered
immagino l'argomento possa considerarsi chiuso ;)

signed, sealed and delivered
?!? che cos'e' lo standard signed, sealed & delivered?
Ciao,
Zeppe

> ?!? che cos'e' lo standard signed, sealed & delivered?
Firmato, sigillato e consegnato... == cosě com'č :-)
--- bye

 Firmato, sigillato e consegnato... == così com'è :-)
Dovrebbe suonare più che altro "fuori dalle scatole definitivamente,
senza possibilità di ripensamento".
E` un pezzo di James Brown tra l'altro ;)