Podejrzewam, że odpowiedź na to pytanie będzie różnić się w zależności od architektury docelowej, ponieważ konwersje mogą (ale nie muszą) wystąpić w sprzęcie. Na przykład, rozważmy następujący kod, który powoduje pewne wzajemne przekształcenia między int i 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?
}
Kiedy próbowałem skompilować to z g ++ (jestem na Ubuntu, x86) z ustawieniami domyślnymi i używane gdb rozbierać :
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
Uwaga instrukcje z CVT-prefiksem mnemoników. Są to instrukcje konwersji. Tak więc w tym przypadku konwersja odbywa się w sprzęcie za pomocą kilku instrukcji. Tak więc, w zależności od tego, ile cykli kosztują te instrukcje, może być dość szybki. Ale znowu, inna architektura (lub inny kompilator) może zmienić historię.
Edycja: W zabawnej notatce bocznej istnieje dodatkowa konwersja dzięki temu, że przypadkowo podałem 0.5 zamiast 0.5f. Właśnie dlatego jest tam cvtpd2ps op.
Edycja: x86 ma wsparcie FP przez długi czas (od lat 80.), więc kompilatory C++ kierujące się do x86 będą na ogół korzystały ze sprzętu (chyba że kompilator jest poważnie za czasami). Dzięki Hot Licks za wskazanie tego.
Tak, istnieją koszty konwersji między różnymi typami. Mogę dać dogłębną odpowiedź, jeśli nikt nie zrobi, zanim wrócę z mojej śródokresu. – Mysticial
Ponieważ operacje zmiennoprzecinkowe nie są trywialne w kategoriach arytmetyki base-2, kompilatory często emitują funkcje pomocnicze (zobacz, dlaczego potrzebne jest użycie libgcc?) I które mogą poważnie wpłynąć na wydajność. –
Chodzi o to, że twój program wykonuje ** nie ** i wykonuje operacje na operandach różnych typów. Promuje argumenty według np. C99's 6.3.1.8 Zwykłe konwersje arytmetyczne, a następnie odbywa się operacja n-ary, zwykle z argumentami tego samego typu (jest kilka wyjątków, ale żaden nie dotyczy typów zmiennoprzecinkowych). –