首页
社区
课程
招聘
[讨论][讨论]一段有问题的代码
发表于: 2011-8-8 15:27 5133

[讨论][讨论]一段有问题的代码

2011-8-8 15:27
5133
源程序:

int _tmain(int argc, _TCHAR* argv[])
{
float fFirst = 360.00f;
float fSecond = 1.20f;
float fValue1 = fFirst/fSecond;

float fValue3 = (int)fValue1;

float fValue2 = (int)(fFirst/fSecond);

return 0;
}

fValue3 结果是300.00
而fValue2结果是299.00

首先,我很鄙视这种强转。但是,本着严谨的态度,我分析了一下:

以下是反汇编的程序:

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
004113D0 55 push ebp
004113D1 8B EC mov ebp,esp
004113D3 81 EC 00 01 00 00 sub esp,100h
004113D9 53 push ebx
004113DA 56 push esi
004113DB 57 push edi
004113DC 8D BD 00 FF FF FF lea edi,[ebp-100h]
004113E2 B9 40 00 00 00 mov ecx,40h
004113E7 B8 CC CC CC CC mov eax,0CCCCCCCCh
004113EC F3 AB rep stos dword ptr es:[edi]
float fFirst = 360.00f;
004113EE D9 05 40 58 41 00 fld dword ptr [__real@43b40000 (415840h)]
004113F4 D9 5D F8 fstp dword ptr [fFirst]
float fSecond = 1.20f;
004113F7 D9 05 3C 58 41 00 fld dword ptr [__real@3f99999a (41583Ch)]
004113FD D9 5D EC fstp dword ptr [fSecond]
float fValue1 = fFirst/fSecond;
00411400 D9 45 F8 fld dword ptr [fFirst]
00411403 D8 75 EC fdiv dword ptr [fSecond]
00411406 D9 5D E0 fstp dword ptr [fValue1]

float fValue3 = (int)fValue1;
00411409 D9 45 E0 fld dword ptr [fValue1]
0041140C E8 D0 FC FF FF call @ILT+220(__ftol2_sse) (4110E1h)
00411411 89 85 00 FF FF FF mov dword ptr [ebp-100h],eax
00411417 DB 85 00 FF FF FF fild dword ptr [ebp-100h]
0041141D D9 5D D4 fstp dword ptr [fValue3]

float fValue2 = (int)(fFirst/fSecond);
00411420 D9 45 F8 fld dword ptr [fFirst]
00411423 D8 75 EC fdiv dword ptr [fSecond]
00411426 E8 B6 FC FF FF call @ILT+220(__ftol2_sse) (4110E1h)
0041142B 89 85 00 FF FF FF mov dword ptr [ebp-100h],eax
00411431 DB 85 00 FF FF FF fild dword ptr [ebp-100h]
00411437 D9 5D C8 fstp dword ptr [fValue2]

return 0;
0041143A 33 C0 xor eax,eax
}

接下来,跟到了__ftol2_sse内部的实现:

ftol2.asm ------------
00411670 83 3D 98 75 41 00 00 cmp dword ptr [___sse2_available (417598h)],0
00411677 74 2D je _ftol2 (4116A6h)
00411679 55 push ebp
0041167A 8B EC mov ebp,esp
0041167C 83 EC 08 sub esp,8
0041167F 83 E4 F8 and esp,0FFFFFFF8h
00411682 DD 1C 24 fstp qword ptr [esp]
00411685 F2 0F 2C 04 24 cvttsd2si eax,mmword ptr [esp]

执行完毕后,发现此时的eax是12B(299),12C(300)

不知道原因是啥,大侠请指教!

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 967
活跃值: (1138)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
fld fild
2011-8-8 17:23
0
雪    币: 225
活跃值: (309)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感觉是SSE指令:cvttsd2si的处理
2011-8-9 15:06
0
雪    币: 193
活跃值: (64)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
fFirst/fSecond=+2.99999988079071499e+0002

fValue1 = fFirst/fSecond 这是牵扯到 要把2.99999988079071499e+0002存储到内存中
因为精度问题,这时会在fValue1 的内存地址写入+3.00000000000000000e+0002 即300
转化成整数就是300
而 (int)(fFirst/fSecond); 的结果仍然放到ST0中,这只在用(int)转换,直接截取了整数部分。
2011-8-9 15:33
0
游客
登录 | 注册 方可回帖
返回
//