- 主题:软件bug么
下面这段代码:
float a = 1.8;
int b = 110 * a / 11;
在 visual studio 2005下面 32位编译时 b的值为17。
换成64位编译为18。
--
FROM 223.104.211.*
x86 debug:
pushebp
movebp, esp
subesp, 216; 000000d8H
pushebx
pushesi
pushedi
leaedi, DWORD PTR [ebp-216]
movecx, 54; 00000036H
moveax, -858993460; ccccccccH
rep stosd
fld DWORD PTR __real@3fe66666
fstp DWORD PTR _a$[ebp]
fld DWORD PTR _a$[ebp]
fmul QWORD PTR __real@405b800000000000
fdiv QWORD PTR __real@4026000000000000
call __ftol2_sse
mov DWORD PTR _b$[ebp], eax
x86 release:
push 17 ; 00000011H
push OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
【 在 z16166 的大作中提到: 】
: 看汇编代码
--
修改:grainbuds FROM 101.80.114.*
FROM 101.80.114.*
哦,学习了
【 在 z16166 (Netguy) 的大作中提到: 】
: 因为VS2005用的是基本浮点指令的问题吧
: 单步跟进_ftol2_sse()这个内部看最终执行的是什么"浮点 -> 整数"的转换指令,如果是cvttsd2si,结果就是17。
:
: VS2019用的是SSE指令,和基本浮点指令的计算精度可能不同。这个网站直接能看汇编
--
FROM 101.80.114.*
多谢,我测试了一下,使用fpu,1.8变成了1.7999999523162841,乘完110 之后变成了197.99999475479126,再除以11后就是17.999999523162841,最终取整就成了17。
而使用sse后乘的结果是198.0。
【 在 foliver (Oliver) 的大作中提到: 】
: 和寄存器指令有关最开始。
: 最开始浮点数都是fpu计算,fpu寄存器都是80bits大小,不管float还是double,没有区别,指令也一样。
:
: 后来2000年前后,intel推广sse,引入xmm寄存器,遵从float/double的大小,使用不同的指令。这时的float才是真float。
--
FROM 223.104.211.*