変換はハードウェアで発生する可能性があります (発生しない可能性があるため)。たとえば、次のコードを考えてみましょう。これにより、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.5f ではなく 0.5 を誤って指定したため、余分な変換があります。そのため、cvtpd2ps op がそこにあります。
編集: x86 は長い間 (80 年代から) FP をサポートしてきたため、x86 をターゲットとする C++ コンパイラは通常、ハードウェアを利用します (コンパイラが大幅に時代遅れでない限り)。これを指摘してくれたHot Licksに感謝します。