一个有趣的问题

代码如下:

#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 %.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版由于编译器为其进行了优化,导致精度丢失。

一个有趣的问题》上有4条评论

  1. Greetings from California! I’m bored at work so I decided to check out your blog on my iphone during lunch break. I enjoy the knowledge you provide here and can’t wait to take a look when I get home. I’m amazed at how fast your blog loaded on my cell phone .. I’m not even using WIFI, just 3G .. Anyways, wonderful blog!

  2. Admiring the time and effort you put into your blog and in depth information you present. It’s good to come across a blog every once in a while that isn’t the same unwanted rehashed information. Excellent read! I’ve saved your site and I’m adding your RSS feeds to my Google account.

发表评论

电子邮件地址不会被公开。