embarcadero c ++ 10.2.3双重比较

时间:2018-11-06 20:38:07

标签: 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);

结果不正确”。为什么??

应为z1> z2 = false;但这是真的。

如果我使用标准编译器,那还可以。但是clang编译器给出了错误的结果。

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

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

1 个答案:

答案 0 :(得分:3)

您是对的:这两个结果应该相同。缺省情况下,编译器通常在非一致性模式下运行浮点计算,这可能会引起类似这样的意外。可能发生的情况是,代码以高于双精度的精度计算了2.0 / 5.0,然后将结果四舍五入为z1后将结果存储在double中。然后,它以高于双精度的精度再次计算2.0 / 5.0,并将该值(未取整)与它先前存储的取整值进行比较。就像将1/3计算为.333和.3333一样,得出的结论是1/3不等于1/3。

检查编译器设置中与快速浮点相关的内容。

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