PDA

View Full Version : [C++] Errore di compilazione


nikaldo
13-10-2009, 23:34
In internet ho trovato questo codice sorgente in C++ per la ricerca di numeri primi , ma provandolo sul compilatore C++ 6 della Microsoft
mi segnala un errore di cui non riesco a trovare la soluzione, sperando che qualcuno possa aiutarmi ringrazio in anticipo.

_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

#include <iostream>
#include <cmath>
using namespace std;

void numeri_primi(int max)
{
int k=(int)(max/trunc(log(max))); /* usa la stima di Gauss sul numero dei numeri primi, valido per max che entra in una variabile */
int i, j , pasI=2;
int *dp=new int[k];
int *m=new int[k];
int massimo=1,prova;

dp[0]=5;
m[0]=25;

if (max >=2){
cout<<2<<endl;
}
if (max >=3){
cout<<3<<endl;
}
if (max >=5){
cout<<5<<endl;
}

for(i=7; i<max ;i+=(pasI=6-pasI)) // evita i multipli di 3
{
/* cerca i divisori tra i primi già trovati fino a sqrt(i) */
for(prova = dp[j=0]; (i%m[j]) && prova*prova < i; prova=dp[++j])
{
if(i>m[j])
m[j]+= 2*prova;
}
if(i!=m[j])
{
cout<<i<<endl;
dp[massimo]=i;
m[massimo++]=i*i;
}
}

delete dp;
delete m;
}

int main(void)
{
int i;

cout<<"Introdurre il numero Max : "<<endl;
cin>>i;
numeri_primi(i);
}


____________________________________________________________________________________________________________________________

Compiling...
Numeriprimi.cpp
c:\n_prime\numeriprimi.cpp(7) : error C2065: 'trunc' : undeclared identifier
c:\n_prime\numeriprimi.cpp(53) : warning C4508: 'main' : function should return a value; 'void' return type assumed
Error executing cl.exe.

N_prime.exe - 1 error(s), 1 warning(s)

Torav
14-10-2009, 00:44
mai sentito parlare della funzione trunc O_O
Cercando su google ho visto che dovrebbe comportarsi come la funzione floor. Prova a sostituire trunc con floor e la cosa dovrebbe funzionare

cionci
14-10-2009, 13:16
trunc non esiste perché il troncamento si fa semplicemente convertendo da floating point ad intero.

Torav
14-10-2009, 23:12
trunc non esiste perché il troncamento si fa semplicemente convertendo da floating point ad intero.

ah quindi non è equivalente a floor? Allora avevo capito male :stordita:

cionci
15-10-2009, 07:27
ah quindi non è equivalente a floor? Allora avevo capito male :stordita:
E' equivalente solo per i floating point positivi ;)

flloor(-0.1) ritorna -1, (int)-0.1 ritorna 0
flloor(-2.1) ritorna -3, (int)-2.1 ritorna -2

tomminno
15-10-2009, 08:18
Una precisazione: su cpu intel il cast da float ad int è critico per le prestazioni in quanto viene svuotata completamente la pipeline della fpu e viene modificata la modalità di funzionamento della stessa (da arrotondamento a troncamento) per eseguire l'operazione e viceversa per poter eseguire tutte le operazioni seguenti.
Il C99 fornisce le funzioni lrint,lrintf ecc che evitano questo problema.

cionci
15-10-2009, 12:10
Comunque lrint non fa la stessa cosa della conversione ad intero. Fa l'arrotondamento.
int main()
{
printf("%ld\n", lrint(-0.9));
printf("%ld\n", lrint(-0.1));
printf("%d\n", (int)-0.9);
}
L'output sarà:
-1
0
0

Questa cosa del cambio di modalità dell'unità floating point sinceramente non la sapevo. Ora provo a tradurre in codice assembly ;)

cionci
15-10-2009, 12:25
Per la conversione in asm x64 viene usata questa istruzione: http://www.sesp.cse.clrc.ac.uk/html/SoftwareTools/vtune/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/mergedProjects/instructions/instruct32_hh/vc67.htm
Quindi per i compilatori a 64 bit non ci sono problemi.

In effetti in asm x86 si vede l'istruzione fldcw che svuota la pipeline.

nikaldo
15-10-2009, 23:11
Vi ringrazio per l'aiuto , sostituendo a " trunc " l'istruzione "int" il programma funziona perfettamente; mi resta solo la curiosità del perchè sia stata utilizzato questo tipo di istruzione in C++ pechè a quanto ho potuto appurare è invece tipica del linguaggio Visual J++.

cionci
16-10-2009, 07:21
Non ne ho idea...probabilmente è stato utilizzato qualche compilatore che ha nella libreria math questa istruzione non standard.