Tôi nghi ngờ câu trả lời cho câu hỏi này sẽ thay đổi theo kiến trúc đích, bởi vì các chuyển đổi có thể (nhưng có thể không) xảy ra trong phần cứng. Ví dụ, hãy xem xét đoạn mã sau, gây ra một số interconversions giữa int và 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?
}
Khi tôi cố gắng biên dịch này với g ++ (Tôi đang trên Ubuntu, x86) với các thiết lập mặc định, và sử dụng gdb để tháo rời :
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
Lưu ý các hướng dẫn với tiền tố có tiền tố cvt. Đây là các hướng dẫn chuyển đổi. Vì vậy, trong trường hợp này, quá trình chuyển đổi diễn ra trong phần cứng chỉ trong một số hướng dẫn. Vì vậy, tùy thuộc vào bao nhiêu chu kỳ các hướng dẫn chi phí, nó có thể được hợp lý nhanh chóng. Nhưng một lần nữa, một kiến trúc khác (hoặc trình biên dịch khác) có thể thay đổi câu chuyện.
Chỉnh sửa: Trên một lưu ý thú vị, có thêm một chuyển đổi trong đó do tôi vô tình chỉ định 0,5 thay vì 0,5f. Đó là lý do tại sao cvtpd2ps op nằm trong đó.
Chỉnh sửa: x86 đã có hỗ trợ FP trong một thời gian dài (từ thập niên 80), vì vậy trình biên dịch C++ nhắm mục tiêu x86 thường sẽ sử dụng phần cứng (trừ khi trình biên dịch nghiêm túc sau thời gian). Cảm ơn Hot Licks vì đã chỉ ra điều này.
Có, có chi phí để chuyển đổi giữa các loại khác nhau. Tôi có thể đưa ra một câu trả lời chuyên sâu nếu không ai khác làm vào lúc tôi trở về từ giữa kỳ. – Mysticial
Vì các phép toán dấu phẩy động không quan trọng về số học cơ sở-2, các trình biên dịch thường phát ra các hàm trợ giúp (xem tại sao libgcc là cần thiết?) Và có thể ảnh hưởng nghiêm trọng đến hiệu suất. –
Vấn đề là, chương trình của bạn không ** thực hiện các thao tác n-ary trên các toán hạng của các kiểu khác nhau. Nó thúc đẩy các đối số theo ví dụ: C99 6.3.1.8 Chuyển đổi số học thông thường, và sau đó hoạt động n-ary diễn ra, thường với các đối số cùng loại (có một vài ngoại lệ nhưng không có ngoại lệ nào liên quan đến các loại dấu phẩy động). –