Вы можете выполнить битовую перестановку чисел с плавающей запятой, но правильное понимание этого зависит от точного знания двоичного представления с плавающей запятой. Для большинства машин в наши дни это IEEE-754 , что достаточно просто. Например, 32-разрядные числа с плавающей запятой IEEE-754 имеют 1 знаковый бит, 8 битов экспоненты и 23 бита мантиссы, поэтому вы можете использовать сдвиги и маски для извлечения этих полей и выполнения действий с ними. Таким образом, выполнить trunc (округление до целого в 0) довольно просто:
float trunc(float x) {
union {
float f;
uint32_t i;
} val;
val.f = x;
int exponent = (val.i >> 23) & 0xff; // extract the exponent field;
int fractional_bits = 127 + 23 - exponent;
if (fractional_bits > 23) // abs(x) < 1.0
return 0.0;
if (fractional_bits > 0)
val.i &= ~((1U << fractional_bits) - 1);
return val.f;
}
Сначала мы извлекаем поле экспоненты и используем его для вычисления количества битов после
десятичная точка присутствует в числе. Если размер мантиссы превышает размер, мы просто возвращаем 0. В противном случае, если есть хотя бы 1, мы маскируем (очищаем) столько младших битов. Довольно просто Мы игнорируем denormal, NaN и бесконечность ее, но это работает нормально, так как они имеют показатели всех 0 или всех 1, что означает, что мы в конечном итоге преобразуем денорм в 0 (они попадают в первую очередь, если, наряду с маленькими нормальные числа) и оставив NaN / Inf без изменений.
Чтобы взять слово, вам также нужно взглянуть на знак и округлить отрицательные числа «вверх» в сторону отрицательной бесконечности.
Обратите внимание, что это почти наверняка медленнее, чем использование выделенных операций с плавающей запятой, поэтому подобные вещи действительно полезны, только если вам нужно использовать числа с плавающей запятой на оборудовании, которое не имеет встроенной поддержки с плавающей запятой. Или если вы просто хотите поиграть и узнать, как эти вещи работают на низком уровне.