Подтвердить что ты не робот

Двойное преобразование в int за сценой?

Мне просто интересно узнать, что происходит за сценой, чтобы преобразовать double в int, скажем, int (5666.1)? Это будет дороже, чем static_cast дочернего класса для родителя? Поскольку представление int и double принципиально иное, там будут временные, созданные во время процесса и дорогостоящие тоже.

4b9b3361

Ответ 1

Любой процессор с собственной плавающей точкой будет иметь команду для преобразования данных с плавающей точкой в ​​целочисленные. Эта операция может занять от нескольких циклов до многих. Обычно для 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;

I.e., несколько команд распаковки и сдвиг.

Ответ 2

Всегда есть специальная инструкция FPU, которая выполняет задание cvttsd2si, если генератор кода использует набор инструкций Intel SSE2. Это быстро, но не так быстро, как статический бросок. Обычно это не требует никакого кода.

Ответ 3

static_cast зависит от генерации кода компилятора С++, но обычно не имеет затрат времени исполнения, поскольку изменение указателя вычисляется во время компиляции на основе предполагаемой информации в составе.

Когда вы конвертируете double в int, в системе x86 компилятор будет генерировать команду FIST (плавающая точка/целочисленное преобразование), и FPU выполнит преобразование. Это преобразование может быть реализовано в программном обеспечении, и это делается на определенном оборудовании, или если программа требует этого. Библиотека GNU MPFR способна выполнять двойные и внутренние преобразования и будет выполнять одно и то же преобразование на всех аппаратных средствах.