【发布时间】:2010-02-03 04:30:47
【问题描述】:
我只是想知道将 double 转换为 int 的幕后发生了什么,比如 int(5666.1) ?这会比子类对父类的 static_cast 更昂贵吗?由于 int 和 double 的表示形式根本不同,因此在此过程中会创建临时变量,而且成本也很高。
【问题讨论】:
标签: c++ floating-point double int
我只是想知道将 double 转换为 int 的幕后发生了什么,比如 int(5666.1) ?这会比子类对父类的 static_cast 更昂贵吗?由于 int 和 double 的表示形式根本不同,因此在此过程中会创建临时变量,而且成本也很高。
【问题讨论】:
标签: c++ floating-point double int
任何具有本机浮点的 CPU 都有将浮点数转换为整数数据的指令。该操作可能需要几个周期到多个周期。通常对于 FP 和整数有单独的 CPU 寄存器,因此您还必须随后将整数移动到整数寄存器才能使用它。这可能是另一种操作,可能很昂贵。请参阅您的处理器手册。
PowerPC 尤其不包括将 FP 寄存器中的整数移动到整数寄存器的指令。必须从 FP 存储到内存并加载到整数。因此,您可以说创建了一个临时变量。
在没有硬件 FP 支持的情况下,数字必须被解码。 IEEE FP 格式为:
sign | exponent + bias | mantissa
要转换,您必须执行类似的操作
// Single-precision format values:
int const mantissa_bits = 23; // 52 for double.
int const exponent_bits = 8; // 11 for double.
int const exponent_bias = 127; // 1023 for double.
std::int32_t ieee;
std::memcpy( & ieee, & float_value, sizeof (std::int32_t) );
std::int32_t mantissa = ieee & (1 << mantissa_bits)-1 | 1 << mantissa_bits;
int exponent = ( ieee >> mantissa_bits & (1 << exponent_bits)-1 )
- ( exponent_bias + mantissa_bits );
if ( exponent <= -32 ) {
mantissa = 0;
} else if ( exponent < 0 ) {
mantissa >>= - exponent;
} else if ( exponent + mantissa_bits + 1 >= 32 ) {
overflow();
} else {
mantissa <<= exponent;
}
if ( ieee < 0 ) mantissa = - mantissa;
return mantissa;
即,一些解包指令和移位。
【讨论】:
如果代码生成器使用英特尔 SSE2 指令集,则总是有一条专用的 FPU 指令来完成工作,即 cvttsd2si。这很快,但不如静态演员表快。这通常根本不需要任何代码。
【讨论】:
【讨论】:
cvttsd2si。
cvttsd2si 存在。但是是否有编译器将已弃用的 x87 ins 用于 x86-64?