Двойное преобразование в int за сценой? - PullRequest
12 голосов
/ 03 февраля 2010

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

Ответы [ 3 ]

18 голосов
/ 03 февраля 2010

Любой ЦП с собственной плавающей точкой будет иметь инструкцию для преобразования данных с плавающей точкой в ​​целочисленные данные.Эта операция может занять от нескольких циклов до многих.Обычно существуют отдельные регистры ЦП для FP и целых чисел, поэтому вам также необходимо впоследствии переместить целое число в регистр целых чисел, прежде чем вы сможете его использовать.Это может быть другая операция, возможно, дорогая.См. Руководство по вашему процессору.

В частности, 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;

Т.е. несколько инструкций по распаковке и сдвиг.

4 голосов
/ 03 февраля 2010

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

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

4 голосов
/ 03 февраля 2010

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

...