Двоичный int, чтобы удвоить без Typecasting - PullRequest
2 голосов
/ 21 февраля 2011

Я занимаюсь программированием микроконтроллера на C. Я читаю с разных датчиков 4 байта, которые представляют либо float, int, либо unsigned int.В настоящее время я храню их в формате unsigned int в микроконтроллере, хотя данные могут быть float, поскольку для микроконтроллера это всего лишь байты.Эти данные затем передаются на ПК.Я хочу, чтобы ПК интерпретировал двоичные данные как float или int или unsigned int всякий раз, когда я захочу.Есть способ сделать это?

Пример.

unsigned int value = 0x40040000; // This is 2.0625 in double
double result = convert_binary_to_double(value); // result = 2.0625

Спасибо.

PS: я пробовал типизацию, но это не работает.

Ответы [ 7 ]

7 голосов
/ 21 февраля 2011

Помните, что то, что вы просите, не является полностью переносимым, что-то вроде этого, вероятно, сработает:

float value = *(float *)&bits;

Другая очевидная возможность - использовать объединение:

typedef union { 
    unsigned int uint_val;
    int          int_val;
    float        float_val;
} values;

values v;
v.uint_val = 0x40040000;
float f = v.float_val;

Любой из них, вероятно, будет работать нормально, но ни один не гарантирует переносимость.

2 голосов
/ 21 февраля 2011

Самый короткий способ - привести адрес float (соответственно int) к адресу int (соответственно float) и разыменовать это: например, double result = * (float*) &value;.Ваш оптимизирующий компилятор может скомпилировать этот код во что-то, что работает не так, как вы предполагали (см. строгие правила псевдонимов ).

Способ, который работает чаще, состоит в использовании объединения с *Поле 1010 * и поле float.

1 голос
/ 21 февраля 2011

Это ужасная работа:)
это говорит об их представлении в памяти (согласно IEEE754), поэтому при различных побитовых операциях вы должны извлечь знак, экспоненту и мантиссу из вывода вашего микроконтроллера, а затем выполнить number = (-1)^e * mantissa ^ (exponent - 1023).

1 голос
/ 21 февраля 2011

Почему бы вам не сделать что-то вроде: double *x = &value; или союз?

0 голосов
/ 21 февраля 2011

Вы пытались использовать функцию itoa () ?Это аккуратная маленькая функция, часто используемая для преобразования int в ASCII.

0 голосов
/ 21 февраля 2011

На ПК их также просто байты, и как таковые они могут быть скопированы в любое 4-байтовое Int, 4-байтовое Unsigned Int или 4-байтовое поле Float, и компьютер будет вполне доволен. Вам нужно будет обернуть их, или как-то пометить их как int, unsigned или float. НЕТ СПОСОБА, который компилятор может определить, глядя на любой 32-битный набор битов, что это за тип. - Если вам нужно лучшее объяснение, прокомментируйте меня, и я дам вам действительно длинную версию - Джо - Может быть, я неправильно понял ваш вопрос. Я думал, что вы хотите отправить более 4 байтов данных, и компьютер должен знать, были ли данные изначально 32-битными Int, 32-битными Unsigned или 32-битными Float. Компьютер не может знать ответ без дополнительной информации.

0 голосов
/ 21 февраля 2011

Что вы имеете в виду, говоря, что «приведение типов не работает»?Что именно ты попробовал?Например, вы пробовали что-то вроде этого:

double convert_binary_to_double(unsigned int value)
{
    return *((double*)&value);
}
...