【问题标题】:Compiling gives different results than windows compiler编译给出的结果与 Windows 编译器不同
【发布时间】:2014-12-21 11:38:59
【问题描述】:

我尝试编译和运行一些我多年前在带有代码块的 Windows 上开发的旧 C 程序。

我没有从 gcc 得到错误并且程序正确执行。仅在某些情况下(某些初始条件),我没有得到与以前相同的数值结果!我没有更改程序中的任何内容(除了 sed ^M 字符)。

我一开始以为是因为两个 scanf 函数。但不是。我删除了它们并得到了同样的错误结果。

有没有人在使用 Windows C 代码到 linux 之前遇到过这种奇怪的行为?

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "differentialeqsolve.h"

#define TINY 1.0e-30

/*----------------------------------------------------------------------------------------------*/
/*main*/
/*----------------------------------------------------------------------------------------------*/
int main(void){

/*miscellaneous variables*/
int i,k,dummy;
int N=4;                          /*nb equa diff +1 (we don't want to use f[0])*/

/*output files*/
char namefile[20]={0};        /*file for couplings*/
FILE * file[N];

/*Runge Kutta variables*/
double accuracy=1e-7;             /*minimal precision required for values of f obtained by rk*/
double h=1.0e-7;                  /*initial step for RG (for the first iteration)*/
double htry,hdid,hnext;           /*initial/effective/final step for rk5adapt*/
double t=0.;                      /*RG time*/
double limite=1.0e12;              /*cutoff limit for the strong coupling*/

double U,J;                    /*lattice parameters for initial conditions*/
int NN;                           /*number of spin components*/

double thetamin,thetamax,dtheta;
double theta;
double R=0.1;

int n=100;                        /*number of points in the calculation around the ring*/

double f[N];
double df[N];
double fscal[N];
double g[N];                      /*renormalized (by f1) couplings*/

/*opening output files*/
for (k = 1 ; k < N ; k++ )
        {sprintf(namefile,"g%d.dat",k);
        file[k]=fopen(namefile, "w");}

/*initialization of couplings f[]*/

NN=3;

thetamin = -0.1;
thetamax = 0.1;

dtheta=(thetamax-thetamin)/((float) n);
printf("dtheta=%.10lf\n",dtheta);

for(i=0;i<=n;i++){
   theta=thetamin+i*dtheta;
   U=R*cos(theta);
   J=R*sin(theta);

   /*initialization of table df[]*/
    for(k=1;k<N;k++) df[k]=0;

    f[1]=-2*NN*U-3*NN*J;
    f[2]=-2*NN*U+NN*J+2*NN*NN*J;
    f[3]=-2*NN*U+NN*J;

    t=0.;              /*initialization of RG time*/

    /*initialization of RG time step for rk5adapt*/
    htry=h;
    /*calculation of the scaling to calculate precision*/
    for(k=1;k<N;k++)
        fscal[k]=fabs(f[k])+fabs(df[k]*htry)+TINY;

    /* ********************************************************/
    /*iteration of RG until at least one of the couplings reaches the cutoff "limite"*/
    /* ********************************************************/
    for(;;){
    /*calculation of f(t+h) with rk5adapt*/
        rk5adapt(f,df,N,NN,&t,htry,accuracy,fscal,&hdid,&hnext,dfunctions);
        /*new time is readily set by rk5adapt*/
        /*new step (set as hnext by rk5adapt)*/
        htry=hnext;
        /*new scaling fscal*/
        for(k=1;k<N;k++)
            fscal[k]=fabs(f[k])+fabs(df[k]*htry)+TINY;

    /*Stop RG iteration when at least one of the couplings reaches the cutoff limit*/
        for(k=1;k<N;k++)
            {if(fabs(f[k])>=limite) {goto RGstop;}}

    }
    RGstop : if(f[1]>0) for(k=1;k<N;k++)
             {
                g[k]=f[k]/f[1];
                fprintf(file[k],"%lf %lf\n",theta,g[k]);
             }
             else printf("%lf, g[1]<0\n",theta);

/*end theta*/
}

for ( k = 1 ; k < N ; k++ )
{
    fclose(file[k]);
}

return 0;

}

【问题讨论】:

  • 贴出不同结果的代码
  • 我认为您将不得不在各个点输出变量,直到找到具体的差异。另外,尝试在 Windows 下使用 GCC 编译,看看这是平台问题还是编译器问题。
  • 如果编译器之间的行为发生变化,您可能有......未定义的行为。
  • 我建议您的操作系统的位深度变化可能是数字变化的来源——32 位系统可能存储​​一些与 64 位系统不同的数值(四舍五入需要在 64 位和 128 位数字中放置不同的值)。您“多年前”使用的操作系统可能是 32 位的;如果您使用的是 64 位 Linux,现在...
  • @bosonfute 结果有何不同?您是否使用相同的处理器以及不同的操作系统运行?不同的 FPU 可以稍微不同地处理浮点运算。这不会导致剧烈的变化(很可能是ε差异),但这些变化加起来可能会有明显的不同。 (只有当旧数据为 2.0 时,您得到 2.00000002 时才会出现这种情况)。

标签: c linux windows compilation


【解决方案1】:

好的,我通过将TINY 参数(参见数值食谱中的龙格库塔)设置为1e-25 解决了这个问题。在设置为1e-30之前。

显然,我的编译器不会像我的旧编译器那样处理 float 和 float 操作。

在 chux 评论之后,我检查了 FLT_EVAL_METHOD 的值,它是 0。将它设置为 2 稍微改变了我的微分方程的结果,但只有当我将 TINY 设置为不同的值时,我才最终得到了预期的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 2021-12-10
    • 1970-01-01
    • 2022-10-16
    相关资源
    最近更新 更多