一个有趣的问题

代码如下:

#include “stdafx.h”
#include
#include <float.h>

int _tmain(int argc, _TCHAR* argv[])
{
_controlfp(_MCW_PC, _PC_24);

volatile unsigned long dw = 0x80000052;

unsigned long di = 0;

std::cin >> di;
dw += di;

double d1 = dw;
double d2 = (int)dw;

volatile unsigned long dw1 = (unsigned long)d1;
volatile unsigned long dw2 = (unsigned long)d2;

printf(“%.8x %.8xn”, dw1, dw2);

return 0;
}

这段代码乍看没什么问题,只是将一个无符号的数字转换为双精度,再转换回无符号整型,但是运行Debug版和Release版会发现结果完全不同,查看汇编代码如下

Debug:

double d1 = dw;
0041142A mov eax,dword ptr [dw]
0041142D mov dword ptr [ebp-118h],eax
00411433 mov dword ptr [ebp-114h],0
0041143D fild qword ptr [ebp-118h]
00411443 fstp qword ptr [d1]
double d2 = (int)dw;
00411446 mov eax,dword ptr [dw]
00411449 mov dword ptr [ebp-114h],eax
0041144F fild dword ptr [ebp-114h]
00411455 fstp qword ptr [d2]

Release:

double d1 = dw;
0040103D mov edx,dword ptr [esp]
00401040 fild dword ptr [esp]
00401043 test edx,edx
00401045 jge wmain+4Dh (40104Dh)
00401047 fadd qword ptr [__real@41f0000000000000 (402120h)]
double d2 = (int)dw;
0040104D mov eax,dword ptr [esp]
00401050 mov dword ptr [esp],eax
00401053 fild dword ptr [esp]

原因在于在转换的时候Release版由于编译器为其进行了优化,导致精度丢失。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!