简单的Windows程序在Linux终端上运行,但不在Windows cmd中运行

简单的Windows程序在Linux终端上运行,但不在Windows cmd中运行,c,debugging,cmd,terminal,gdb,C,Debugging,Cmd,Terminal,Gdb,我尝试使用GDB查看“引擎盖下”的代码发生了什么 目前,我的GDB只在linux终端中工作,正如标题中所述,每当我在这里运行这段代码时,我都会得到预期的(逻辑)输出 我认为问题在于func()中的返回 在cmd中运行相同的代码会给出“不相等”,在终端中运行相同的代码会给出“相等”。 为什么会这样 我使用gcc来编译代码 代码如下: #include <stdio.h> double func(){ double y= 5 ; return (double)y/

我尝试使用GDB查看“引擎盖下”的代码发生了什么

目前,我的GDB只在linux终端中工作,正如标题中所述,每当我在这里运行这段代码时,我都会得到预期的(逻辑)输出

我认为问题在于
func()
中的
返回

cmd
中运行相同的代码会给出“不相等”,在
终端中运行相同的代码会给出“相等”。
为什么会这样

我使用
gcc
来编译代码

代码如下:

 #include <stdio.h>

double func(){
     double y= 5 ;
     return (double)y/3;

    /*// Code that works as expected:
    double y= (double)5/3;
    return y;
     */
}

    int main()
{

    double x ;
    x= (double)5/3;

    if (x == func())
        printf("%lf equal to %lf\n", x ,func());
    else
        printf("%lf not equal to %lf\n", x, func());

    return 0;
}
#包括
双func(){
双y=5;
返回(双)y/3;
/*//按预期工作的代码:
双y=(双)5/3;
返回y;
*/
}
int main()
{
双x;
x=(双)5/3;
如果(x==func())
printf(“%lf等于%lf\n”,x,func());
其他的
printf(“%lf不等于%lf\n”,x,func());
返回0;
}

将编译器生成的常量与运行时生成的计算进行比较,然后使用不同的编译器进行编译,并在不同的环境中运行它们(可能在不同的处理器上),而非确定性代码会产生不同的结果。这应该不会让你感到惊讶

此外,double是64位类型,而x86 FPU支持80位浮点。此扩展精度可用于中间计算,但并非所有编译器都将用于编译时常量或运行时计算

所有这些都是浮点结果最低有效位的不确定性因素,通常比较浮点类型是否相等是不明智的。相反,您可以测试一些可接受的小差异:

#define EQUALITY_LIMIT FLT_EPSILON

if ( fabs(x - func()) < EQUALITY_LIMIT )
    printf("%lf equal to %lf\n", x ,func());
else
    printf("%lf not equal to %lf\n", x, func());
\define EQUALITY\u LIMIT FLT\u EPSILON
if(fabs(x-func())
欢迎来到。两个系统上的
x
func()
之间有什么区别?这就是你开始明白的地方。它可能是像1e-29这样的小得离谱但非零的东西。@tadman所以cmd以不同于终端的方式解释双变量。但即便如此,我认为在cmd
func()
x
中,由于它们都是
double
数据类型,因此处理方式相同。您在Windows构建中使用的工具链是什么?这将有一个调试器。在任何情况下,你也可以在Windows中使用GDB(如果使用MinGW)。我在cmd中使用的是
gcc 8.1.0版(x86_64-posix-seh-rev0,由MinGW-W64项目构建)
,效果很好,结果是
等于
。它不是
cmd
的函数,它可能与编译器或编译器设置有关。双精度
可以表示为寄存器(通常为80位)和内存中的64位值。在这两者之间切换可能会导致值的微小差异,这意味着它们不是“等价的”。编译器优化在这里也会带来麻烦,在任何给定情况下都能以最有效的方式表示。因此,“return(double)y/3”是一个运行时生成的计算,它应该有大约80位
x
有64位,这意味着存储了15位。我想
return(double)y/3
存储了更多的数据,这就是等号不起作用的原因。这让我想知道为什么它在终端中工作。@Robert-不,我不是说-它的类型是双精度的,将是64位的。在转换为双精度
之前,80位可以在内部使用,也可以不在内部使用。我只是提出一些问题,这些问题可能会导致比较浮点值是否相等的愚蠢行为。您必须比较汇编级代码和目标处理器FPU实现,以确定在这种情况下结果不同的确切原因。因为您没有指定这些变量(并且仍然奇怪地固定在“terminal”和“cmd”上,而不是生成的代码上)。@Robert:此外,还没有存储15位数字。双精度二进制浮点表示恰好足以将实数近似为至少15位精度的有效十进制数字。前一句中所有斜体部分对于理解这个概念至关重要。十进制和二进制表示法之间没有精确的一致性,您要比较的是二进制值,因此它取决于最低有效位的差异,而不是最低有效十进制数字的差异。