int main(int argc,char *argv[]){ double f = 18.40; printf("%d\n",(int)(10 * f)); return 0;}
VC6.0中的结果为184,而Codeblock的结果为183.为什么?
解决方法 原因是GCC试图尽可能地使代码向后兼容cpu的旧架构,而MSVC试图利用架构的新未来.MSVC生成的代码将两个数字相乘,即10.0×18.40:
.text:00401006 fld ds:dbl_40D168.text:0040100C fstp [ebp+var_8].text:0040100F fld ds:dbl_40D160.text:00401015 fmul [ebp+var_8].text:00401018 call __ftol2_sse
然后调用一个名为__ftol2_sse的函数,在这个函数中,它使用一些名为cvttsd2si的指令将结果转换为整数:
.text:00401189 push ebp.text:0040118A mov ebp,esp.text:0040118C sub esp,8.text:0040118F and esp,0FFFFFFF8h.text:00401192 fstp [esp+0Ch+var_C].text:00401195 cvttsd2si eax,[esp+0Ch+var_C].text:0040119A leave.text:0040119B retn
这条指令cvttsd2si是根据这个page:
Convert scalar double-precision floating-point value (with truncation)
to signed doubleword of quaDWord integer (SSE2)
它基本上将double转换为整数.该指令是Intel Pentium 4引入的名为SSE2的指令集的一部分.
GCC默认不使用此指令集,并尝试使用i386中的可用指令进行 *** 作:
fldl 0x28(%esp)fldl 0x403070fmulp %st,%st(1)fnstcw 0x1e(%esp)mov 0x1e(%esp),%axmov0x004013ac <+32>: movsd 0x18(%esp),%xmm10x004013b2 <+38>: movsd 0x403070,%xmm00x004013ba <+46>: mulsd %xmm1,%xmm00x004013be <+50>: cvttsd2si %xmm0,%eax0x004013c2 <+54>: mov %eax,0x4(%esp)0x004013c6 <+58>: movlxc,%ahmov %ax,0x1c(%esp)fldcw 0x1c(%esp)fistpl 0x18(%esp)fldcw 0x1e(%esp)mov 0x18(%esp),%eaxmov %eax,0x4(%esp)movl x403068,(%esp)call 0x401b44 <printf>mov x0,%eax> type test.c#include <stdio.h>int main(int argc,(int) (10.0 * f)); return 0;}> gcc -Wall test.c -o gcctest.exe -msse2> cl test.c /W3 /link /out:msvctest.exe> gcctest.exe184> msvctest.exe184>x403068,(%esp)0x004013cd <+65>: call 0x401b30 <printf>0x004013d2 <+70>: mov x0,%eax
如果你想让GCC使用cvttsd2si,你需要通过使用标志-msse2编译来告诉它使用SSE2提供的期货,但这也意味着仍然使用旧计算机的一些人将无法运行该程序.有关更多选项,请参见此处Intel 386 and AMD x86-64 Options.
因此在使用-msse2进行编译后,它将使用cvttsd2si将结果转换为32位整数:
现在MSVC和GCC应该给出相同的数字:
总结以上是内存溢出为你收集整理的将double转换为int?全部内容,希望文章能够帮你解决将double转换为int?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)