C ++: Очистить биты с плавающей запятой одинарной точности

В настоящее время я конвертирую программу, изначально предназначенную для OpenCL, в C ++, и у меня возникли некоторые проблемы с одной ее частью.

Один из выражений, обычно используемых в указанной программе, включает в себя получение 32-битного числа с плавающей запятой, преобразование его в целое число (то есть фактически не округление до int, а интерпретацию тех же данных, что и int - подумайте, reinterpret_cast), выполнение на нем некоторой магии битдлинга а затем преобразовать его обратно в число с плавающей запятой (опять же, не фактическое преобразование, а переинтерпретация тех же данных). Хотя это хорошо работает в OpenCL, с C ++ и gcc это нарушает строгие правила псевдонима, нарушая работу программы, если включена оптимизация, и, в зависимости от архитектуры, может включать в себя дорогостоящее хранилище попаданий при загрузке, поскольку регистры с плавающей запятой и целочисленные регистры разделены.

Мне удалось избежать большинства этих выражений, но есть одно, которое я не уверен в том, можно ли это сделать быстрее. По сути, цель состоит в том, чтобы очистить ряд битов справа от числа с плавающей точкой; код OpenCL делает это примерно так:

float ClearFloatBits(float Value, int NumberOfBits) {
    return __int_as_float((__float_as_int(Value) >> NumberOfBits) << NumberOfBits);
}

Так как это по существу округление от указанной (двоичной) цифры, моя версия C ++ теперь выглядит так:

float ClearFloatBits(float Value, int NumberOfBits) {
    float Factor = pow(2.0f, 23 - NumberOfBits);

    return ((int)(Value*Factor))/Factor;
}

Где pow и деление - конечно заменено поиском по LUT и соответствующим умножением, здесь опущено для лучшей читаемости.

Есть ли лучший способ сделать это? Что меня особенно беспокоит, так это преобразование (int) в округление вниз, что, я думаю, является самой дорогой частью. Гарантируется, что переданное в функцию число с плавающей запятой является числом от 1,0 (включительно) до 2,0 (исключая), если это помогает.

Заранее спасибо

5
задан mskfisher 11 May 2012 в 13:42
поделиться