我怀疑这个问题的答案会因目标架构而异,因为转换可以(但可能不会)在硬件中发生。例如,考虑以下代码,它会导致 int 和 float 之间的一些相互转换:
int main (int argc, char** argv)
{
int precoarced = 35;
// precoarced gets forced to float
float result = 0.5 + precoarced;
// and now we force it back to int
return (int)result;
// I wonder what the disassembly looks like in different environments?
}
当我尝试使用 g++(我在 Ubuntu,x86)上使用默认设置编译它,并使用 gdb 进行反汇编时:
0x00000000004004b4 <+0>: push %rbp
0x00000000004004b5 <+1>: mov %rsp,%rbp
0x00000000004004b8 <+4>: mov %edi,-0x14(%rbp)
0x00000000004004bb <+7>: mov %rsi,-0x20(%rbp)
0x00000000004004bf <+11>: movl $0x23,-0x8(%rbp)
0x00000000004004c6 <+18>: cvtsi2sdl -0x8(%rbp),%xmm0
0x00000000004004cb <+23>: movsd 0x10d(%rip),%xmm1 # 0x4005e0
0x00000000004004d3 <+31>: addsd %xmm1,%xmm0
0x00000000004004d7 <+35>: unpcklpd %xmm0,%xmm0
0x00000000004004db <+39>: cvtpd2ps %xmm0,%xmm0
0x00000000004004df <+43>: movss %xmm0,-0x4(%rbp)
0x00000000004004e4 <+48>: movss -0x4(%rbp),%xmm0
0x00000000004004e9 <+53>: cvttss2si %xmm0,%eax
0x00000000004004ed <+57>: pop %rbp
0x00000000004004ee <+58>: retq
请注意带有 cvt 前缀的助记符的说明。这些是转换指令。因此,在这种情况下,转换是在硬件中通过少数指令进行的。因此,根据这些指令花费的周期数,它可能相当快。但同样,不同的架构(或不同的编译器)可能会改变情况。
编辑:有趣的是,由于我不小心指定了 0.5 而不是 0.5f,因此存在额外的转换。这就是 cvtpd2ps 操作在那里的原因。
编辑:x86 已经支持 FP 很长时间了(从 80 年代开始),因此针对 x86 的 C++ 编译器通常会利用硬件(除非编译器严重落后于时代)。感谢 Hot Licks 指出了这一点。