加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

将double转换为int?

发布时间:2020-12-16 10:25:01 所属栏目:百科 来源:网络整理
导读:我的代码如下: int main(int argc,char *argv[]){ double f = 18.40; printf("%dn",(int)(10 * f)); return 0;} VC6.0中的结果为184,而Codeblock的结果为183.为什么? 解决方法 原因是GCC试图尽可能地使代码向后兼容CPU的旧架构,而MSVC试图利用架构的新未
我的代码如下:

int main(int argc,char *argv[])
{

    double f = 18.40;
    printf("%dn",(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   0x403070
fmulp  %st,%st(1)
fnstcw 0x1e(%esp)
mov    0x1e(%esp),%ax
mov    $0xc,%ah
mov    %ax,0x1c(%esp)
fldcw  0x1c(%esp)
fistpl 0x18(%esp)
fldcw  0x1e(%esp)
mov    0x18(%esp),%eax
mov    %eax,0x4(%esp)
movl   $0x403068,(%esp)
call   0x401b44 <printf>
mov    $0x0,%eax

如果你想让GCC使用cvttsd2si,你需要通过使用标志-msse2编译来告诉它使用SSE2提供的期货,但这也意味着仍然使用旧计算机的一些人将无法运行该程序.有关更多选项,请参见此处Intel 386 and AMD x86-64 Options.

因此在使用-msse2进行编译后,它将使用cvttsd2si将结果转换为32位整数:

0x004013ac <+32>:    movsd  0x18(%esp),%xmm1
0x004013b2 <+38>:    movsd  0x403070,%xmm0
0x004013ba <+46>:    mulsd  %xmm1,%xmm0
0x004013be <+50>:    cvttsd2si %xmm0,%eax
0x004013c2 <+54>:    mov    %eax,0x4(%esp)
0x004013c6 <+58>:    movl   $0x403068,(%esp)
0x004013cd <+65>:    call   0x401b30 <printf>
0x004013d2 <+70>:    mov    $0x0,%eax

现在MSVC和GCC应该给出相同的数字:

> 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.exe
184
> msvctest.exe
184
>

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读