请告诉我该代码的操作:
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
答案 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)
访问。