views:

307

answers:

3

I am just curious to know what happens behind the scene to convert a double to int, say int(5666.1) ? Is that going to be more expensive than a static_cast of a child class to parent? Since the representation of the int and double are fundamentally different is there going to be temporaries created during the process and expensive too.

+8  A: 

Any CPU with native floating point will have an instruction to convert floating-point to integer data. That operation can take from a few cycles to many. Usually there are separate CPU registers for FP and integers, so you also have to subsequently move the integer to an integer register before you can use it. That may be another operation, possibly expensive. See your processor manual.

PowerPC notably does not include an instruction to move an integer in an FP register to an integer register. There has to be a store from FP to memory and load to integer. You could therefore say that a temporary variable is created.

In the case of no hardware FP support, the number has to be decoded. IEEE FP format is:

sign | exponent + bias | mantissa

To convert, you have to do something like

int32_t ieee = * reinterpret_cast< int32_t * >( &float_value );
int32_t mantissa = ieee & (1 << 23)-1 | 1 << 23;
int exponent = ( ieee >> 23 & (1 << 8)-1 ) - ( 127 + 23 );
if ( exponent <= -32 ) {
    mantissa = 0;
} else if ( exponent < 0 ) {
    mantissa >>= - exponent;
} else if ( exponent >= 8 ) {
    overflow();
} else {
    mantissa <<= exponent;
}
if ( ieee < 0 ) mantissa = - mantissa;
return mantissa;

I.e., a few bit unpacking instructions and a shift.

Edit: oops, you specified double in the question. Replace 32 with 64, 8 with 11, 127 with 1023, and 23 with 52 to convert it from float to double.

Potatoswatter
+3  A: 

There's invariably a dedicated FPU instruction that gets the job done, cvttsd2si if the code generator uses the Intel SSE2 instruction set. That's fast, but not as fast as a static cast. That doesn't usually require any code at all.

Hans Passant
+3  A: 

The static_cast is dependent on the compiler's C++ code generation, but generally has no runtime cost, as the pointer change is calculated at compile time based on the assumed information in the cast.

When you convert a double to int, on an x86 system the compiler will generate a FIST (Floating-Point/Integer Conversion) instruction, and the FPU will do the conversion. This conversion can be implemented in software, and is done this way on certain hardware, or if the program requires it. The GNU MPFR library is capable of doing double to int conversions, and will perform the same conversion on all hardware.

brianegge
For a modern x86, the compiler can/will generate an SSE2 instruction, not an x87.
MSalters
@MSalters: Depends; some "modern" compilers still codegen to the x87 FPU by default, but yeah, many compilers will emit `cvttsd2si`.
Stephen Canon
Yes, on x86-32 you can't just assume `cvttsd2si` exists. But are there compilers that use the deprecated x87 ins for x86-64?
MSalters