代码如下:
#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版由于编译器为其进行了优化,导致精度丢失。
浙公网安备 33010602011771号