C++ embarcadero c++;10.2.3双重比较

C++ embarcadero c++;10.2.3双重比较,c++,C++,请告诉我在此代码中要执行的操作: UnicodeString Str; double x, y; double z1, z2; x= 2.0; y= 5.0; z1= x/y; z2= x/y; if(z1>z2) Str= "> not ok\n"; else Str= "> ok\n"; Application->MessageBox(Str.c_str(), L"Info", MB_OK

请告诉我在此代码中要执行的操作:

UnicodeString Str;
double        x, y;
double        z1, z2;

  x= 2.0;
  y= 5.0;

  z1= x/y;
  z2= x/y;

  if(z1>z2)
    Str= "> not ok\n";
  else
    Str= "> ok\n";

  Application->MessageBox(Str.c_str(), L"Info", MB_OK);
结果是“>不正常”。为什么

它应该是z1>z2=false;但这是真的

如果我使用标准编译器,那么它就可以了。但是铿锵编译器给出了错误的结果

使用CLang编译器进行反汇编(给出错误结果):

使用标准编译器进行反汇编(给出正确的结果):


你说得对:这两个结果应该是一样的。默认情况下,编译器通常以不一致的模式运行浮点计算,这可能会导致类似这样的意外。可能发生的情况是,代码以高于双精度的方式计算
2.0/5.0
,然后将结果四舍五入到
double
后存储在
z1
中。然后它以高于两倍的精度再次计算
2.0/5.0
,并将该值(未舍入)与之前存储的舍入值进行比较。这就像把1/3算作.333和.3333,得出1/3不等于1/3的结论

检查编译器设置是否与快速浮点相关


编辑:从Clang生成的汇编代码显示了这一点。一个结果存储在内存中(作为64位值),并通过
fld word ptr[epb-$00000098]
访问。另一个被计算并保存在寄存器中(作为80位值),通过
fucomip st(1)

重新打开进行访问。这并不是在用两种不同的方法计算值时得到不同的结果。这是关于用同样的方法计算两次值时得到不同的结果。语言定义要求编译器产生相同的结果。得到不同的结果意味着代码是使用设置不一致模式的开关编译的。这在浮点数学中很常见,但它不是浮点中固有的。这就是为什么应该使用SSE而不是x87。关于两者结果的差异有很多问题:,…我很抱歉。我已经更正了来源。
Unit1.cpp.24: if(z1>z2)
00403D7B DD8568FFFFFF     fld qword ptr [ebp-$00000098]
00403D81 DFE9             fucomip st(1)
00403D83 DDD8             fstp st(0)
00403D85 0F86E7000000     jbe $00403e72
00403D8B EB00             jmp $00403d8d
00403D8D 8B45B0           mov eax,[ebp-$50]
Unit1.cpp.24: if(z1>z2)
004031C7 DD45AC           fld qword ptr [ebp-$54]
004031CA DD45A4           fld qword ptr [ebp-$5c]
004031CD D9C9             fxch st(1)
004031CF DAE9             fucompp 
004031D1 DFE0             fstsw ax
004031D3 F6C445           test ah,$45
004031D6 753D             jnz $00403215