代码如下:

#include "stdafx.h"
#include <iostream>
#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 %.8x\n", 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版由于编译器为其进行了优化,导致精度丢失。