Ответ 1
Вы можете использовать тип punning с объединением,
union {
float f;
uint32_t u;
} un;
un.f = your_float;
uint32_t target = un.u;
чтобы получить бит. Или вы можете использовать memcpy
.
Мне нужно написать число с плавающей точкой с одинарной точностью IEEE в 32-разрядный аппаратный регистр по конкретному адресу. Для этого мне нужно преобразовать переменную типа float в целое число без знака. Я могу получить целочисленное представление следующим образом:
float a = 2.39;
unsigned int *target;
printf("a = %f\n",a);
target = &a;
printf("target = %08X\n",*target);
который возвращает:
a = 2.390000
target = 4018F5C3
Все хорошо. Однако это вызывает предупреждение компилятора "cast.c: 12: warning: назначение из несовместимого типа указателя"
Есть ли другой способ сделать это, не генерируя предупреждение? Это относится к конкретному оборудованию, мне не нужно обрабатывать разные контенты и т.д., И я не хочу прокручивать каждый char по соображениям производительности, как это обычно указывают некоторые другие вопросы. Похоже, что вы можете использовать reinterpret_cast в С++, но я использую C.
Вы можете использовать тип punning с объединением,
union {
float f;
uint32_t u;
} un;
un.f = your_float;
uint32_t target = un.u;
чтобы получить бит. Или вы можете использовать memcpy
.
Вы можете создать тип union
, содержащий float и unsigned int, сохранить значение в члене float, а затем прочитать его из int, например:
union reg_val
{
float f_val;
unsigned int i_val;
} myRegister;
myRegister.f_val = 2.39;
printf("target = %08X", myRegister.i_val);
Если вы пытаетесь просто отобразить интегральное значение float
по мере его хранения в памяти, попробуйте использовать union:
union {
float a;
unsigned int target;
} u;
Сохранить значение поплавка:
u.a = 2.39;
Распечатайте как значения float, так и целочисленные значения:
printf ("a = %f\n", u.a);
printf ("target = %08X\n", u.target); /* you could use %u to show decimal */
Нет предупреждений компилятора. Я использую GNU-компилятор (gcc) для Linux.
Обратите внимание, что target
не является указателем; это красота (и отвратительность) профсоюзов.; -)
EDIT: профсоюзное решение работает везде, где я его пробовал, но где-то там, я был указан в стандартах, которые показали, что он не должен работать. См. Ссылку ниже в комментариях, чтобы найти LOT дополнительную информацию об этом (Спасибо, Даниэль!). Предположим, что я работаю или не должен работать, я буду использовать его с осторожностью, я думаю, что и энтузиазм и т.д. (Удваивается, разбивается на байты и т.д.).
Другое решение - это функция-заглушка asm. Например, на руке:
.globl echo
echo:
bx lr
unsigned int echo ( float );
...
unsigned int ra; float f;
f=1.0;
ra=echo(f);
требуется некоторая разборка, должна быть в системе, которая не имеет fpu и/или использует gprs для переноса плавающих элементов.
memcpy, как уже упоминалось, является самым чистым и надежным и портативным решением (знайте о контенте).