PDA

View Full Version : risultati numerici diversi su diverse piattaforme


cndcnd
28-06-2011, 15:07
Ciao,

il mio problema è il seguente. Il mio programma in c++, compilato con

- gcc su windows
- gcc -pg su windows
- microsoft visula studio su windows
- gcc su linux

fornisce risultai numerici leggermente diversi. Qualcuno sa dirmi dove potrebbe essere il problema?

Grazie,

Alessandro

tuccio`
28-06-2011, 15:09
faresti meglio a pastare il codice, ma se cambia già solo compilando con -pg forse usi qualche variabile non inizializzata?

cndcnd
28-06-2011, 15:25
// ellissoid: semi-axes, centre and displacement
hex=cve->hex; kx=2*DPLMAX/2; dx=(int)cve->hex+cve->dpl[0].xx;
hey=cve->hey; ky=2*DPLMAX/2; dy=(int)cve->hey+cve->dpl[7].yy;
hez=cve->hez; kz=2*DPLMAX/2; dz=(int)cve->hez+cve->dpl[0].zz;
// xxxx
fvx=1; //fvx=(1.00+(0.33*(float)edp->cgare[ci].cgo.dgd[7]/63));
fvy=1; //fvy=(1.00+(0.33*(float)edp->cgare[ci].cgo.dgd[7]/63));
fvz=1; //fvz=(1.00+(0.33*(float)edp->cgare[ci].cgo.dgd[7]/63));
// xxxx
for(bz=(kz-(int)hez-1);bz<(kz+(int)hez+1);bz++)
for(by=(ky-(int)hey-1);by<(ky+(int)hey+1);by++)
for(bx=(kx-(int)hex-1);bx<(kx+(int)hex+1);bx++) {
cve->buf0[bx][by][bz]=6; // no signal
// ellissoid
if((pow((bx-kx)/(hex*fvx),2)+pow((by-ky)/(hey*fvy),2)+pow((bz-kz)/(hez*fvz),2))<=1) {
if((edp->cgare[ci].cgo.ms0==1)||(edp->cgare[ci].cgo.ms0==3))
cve->buf0[bx][by][bz]=7; // normal signal
if( edp->cgare[ci].cgo.ms0==2)
cve->buf0[bx][by][bz]=8; // delete signal
if((edp->cgare[ci].cgo.ms0==1)||(edp->cgare[ci].cgo.ms0==3))
if((bx%NDQXXX==0)&&(by%NDQXXX==0)&&(bz%NDQXXX==0))
cve->buf0[bx][by][bz]=9; // driver signal
ivaro=0;
}
}


Questo è un primo pezzo sospetto. Forse le pow danno risultati diversi su diverse piattaforme Questo è un altro pezzo sospetto:

for(ix=0;ix<2;ix++)
for(iy=0;iy<2;iy++)
for(iz=0;iz<2;iz++)
for(bz=(kz-(int)hez-1);bz<(kz+(int)hez+1);bz++)
for(by=(ky-(int)hey-1);by<(ky+(int)hey+1);by++)
for(bx=(kx-(int)hex-1);bx<(kx+(int)hex+1);bx++) {
if((bx==0)&&(by==0)&&(bz==0)) first=YA; else first=NO;
bufval=cve->buf0[bx][by][bz];
if(bufval!=6) {
if(ix==0) ax=vx+dx+(int)floor(cve->rt[0]*(bx-kx)+cve->rt[1]*(by-ky)+cve->rt[2]*(bz-kz));
else ax=vx+dx+(int)ceil (cve->rt[0]*(bx-kx)+cve->rt[1]*(by-ky)+cve->rt[2]*(bz-kz));
if(iy==0) ay=vy+dy+(int)floor(cve->rt[3]*(bx-kx)+cve->rt[4]*(by-ky)+cve->rt[5]*(bz-kz));
else ay=vy+dy+(int)ceil (cve->rt[3]*(bx-kx)+cve->rt[4]*(by-ky)+cve->rt[5]*(bz-kz));
if(iz==0) az=vz+dz+(int)floor(cve->rt[6]*(bx-kx)+cve->rt[7]*(by-ky)+cve->rt[8]*(bz-kz));
else az=vz+dz+(int)ceil (cve->rt[6]*(bx-kx)+cve->rt[7]*(by-ky)+cve->rt[8]*(bz-kz));
if((ax<0)||(ax>=GRIDXX)||(ay<0)||(ay>=GRIDYY)||(az<0)||(az>=GRIDZZ))
goto GTLBBB;
if((bufval==7)||(bufval==8)) { //normal (7) or delete (8) signal
if(bufval==7) { Moccopy(&moc[0],&mocmother[0]); clcnd=CLSLEEP; }
if(bufval==8) { Moccopy(&moc[0],&edp->moc0[0]); clcnd=CLNOCL0; }
if(done==YA) goto GTLAAA;
if(bufval==7) { cve->smocnew=+1; } // normal
if(bufval==8) { cve->smocnew=-1; } // delete
Dharupd(thid,cve,gi,&edp->cgare[ci],&moc[0],as,0,NO,edp->moclp.marko);
done=YA;
GTLAAA:cvar=cvar;
Daughter(thid,cve,gi,ci,ax,ay,az,clcnd,NO,dhnrnor,edp->moclp.marko);
Dthrmnet(thid,cve,gi,ci,ax,ay,az,clcnd,NO,dhnrnor,edp->moclp.marko);
}
if((ix==1)&&(iy==1)&&(iz==1)) // last cycle to avoid drv get cancelled
if((bufval==9)||(first==YA)) { // driver signal
cve->smocnew++; clcnd=CLSLEEP; // also on mother pos, just once
Moccopy(&moc[0],&mocmother[0]);
Dharupd(thid,cve,gi,&edp->cgare[ci],&moc[0],as,1,YA,edp->moclp.marko);
if(bufval==9) { qx=ax; qy=ay; qz=az; }
if(first==YA) { qx=vx; qy=vy; qz=vz; }
Daughter(thid,cve,gi,ci,qx,qy,qz,clcnd,YA,-1,edp->moclp.marko);
Dthrmnet(thid,cve,gi,ci,qx,qy,qz,clcnd,YA,-1,edp->moclp.marko);
}
GTLBBB:cvar=cvar;
}
}

Anche qui, forse la floor e la ceil sono piattaforma-dipendenti. Se cambio la precisione di alcune variabili, portandole da float a double, i risultati cambiano ancora. Boh!