Разобрать четыре байта с плавающей точкой в ​​C - PullRequest
1 голос
/ 17 апреля 2009

Как мне взять четыре полученных данных байт и собрать их в число с плавающей запятой число?

Прямо сейчас у меня есть байтов , хранящихся в массиве, который будет: receive_data [1] ... receive_data [4] . Я хотел бы сохранить эти четыре байта как одну 32-битную одинарную точность float .

-Спасибо

На самом деле я получаю пакет с 19 байтами в нем и собираю два набора по четыре байта, чтобы получить два числа с плавающей запятой. Таким образом, receive_data [1] до receive_data [4] - это одно число с плавающей запятой, а receive_data [5] до receive_data [8] - прочее ...

* ОБНОВЛЕНИЕ: **** ** Подробнее ...
Первый бит , или знак бит с плавающей точкой , является седьмым битом первого байта , вот что я сделал с проверить ...

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))  


if( CHECK_BIT(received_data[1], 7))  //set or clear LED2
          {LATAbits.LATA2=1;}else{LATAbits.LATA2=0;}  
if( CHECK_BIT(received_data[5], 7))  //set or clear LED3
          {LATAbits.LATA3=1;}else{LATAbits.LATA3=0;}  

Затем я проверил это, отправив чередующиеся положительные и отрицательные числа из моего источника данных, которые должны были соответственно изменить светодиоды, и это работало.

Пока все это верно, это означает, что байты находятся в правильном порядке, но они хранятся в порядке байтов, правильно? Будет ли это храниться в поплавке в правильном порядке? Мне еще не повезло, разбирая байты и читая их как число с плавающей точкой ...

Если у кого-то есть опыт, я использую компилятор C18 MPLAB IDE.

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ:
У меня запущено приложение! Теперь исправлены незначительные ошибки!

СПАСИБО!

Спасибо за помощь, ребята! Я новичок в stackoverflow, но это сообщество здесь действительно круто! И такой инструмент действительно бесценен! Я не могу даже начать говорить вам, сколько времени и разочарований вы все спасли меня!

Ответы [ 5 ]

4 голосов
/ 17 апреля 2009

Вы должны быть уверены, что порядок байтов правильный. Или

float f1 = *(float*)(received_data+1)
float f2 = *(float*)(received_data+5)

или, если вам нужно обратить байты, вам придется скопировать, так что вот альтернатива:

union {
  char chars[4];
  float f;
} u;

for (i = 0; i < 4; i++)
  u.chars[3-i] = received_data[i+1];
float f1 = u.f;     
// ... and similarly for second float

Лучше бы, чтобы эти байты были записаны чем-то вроде инверсии этого процесса (либо вы взяли адрес float и привели его к char *, либо у вас было объединение char[4] и `поплавок.)

0 голосов
/ 17 апреля 2009

Вот как я буферизирую float:

static char* bufferFloat    (int* bLen, float value) {
*bLen = sizeof(float);
char* buf = malloc (*bLen);
int storage;

memcpy (&storage, &value, sizeof (int));
uint32_t val = htonl (storage);
memcpy (buf, &val, *bLen);

return buf;
}

Вот так я получаю число:

static float readFloat (char* buf, int* bLen) {
float ret;
int temp;

if (*bLen < sizeof (float)) {
    *bLen = 0;
    return 0.0f;
}

memcpy (&temp, buf, sizeof (int));
uint32_t val = htonl(temp);
memcpy (&ret, &val, sizeof (float));
*bLen = sizeof (float);

return ret;
}

Это часть некоего хобби сетевого кода, который я написал. Я надеюсь, что это помогает, и, кажется, работает отлично для меня. : D

На самом деле, если вы хотите этот сетевой код, перейдите сюда: http://cgi.cse.unsw.edu.au/~robertm/myProjects.php и найти правильный проект.

0 голосов
/ 17 апреля 2009

Как насчет простого копирования данных через memcpy?

inline float FloatFromByteArray (const unsigned char * received_data)
{
  float f;
  memcpy (&f, received_data, sizeof (float));
  return f;
}

Копирует данные, начиная с receive_data [0]. Если вы хотите скопировать данные из Receive_data [1], просто добавьте смещение внутри memcpy.

inline float FloatFromByteArray (const unsigned char * received_data)
{
  float f;
  memcpy (&f, received_data+1, sizeof (float));
  return f;
}
0 голосов
/ 17 апреля 2009

Вы можете собрать их в порядке, который зависит от порядка байтов вашей машины, затем привести к float* и использовать этот указатель для доступа к ним.

Как правило, вы также помещаете их в data[0] ... data[3]. Итак ...

char *data;

//Assemble in the *right* order
data[0] = received_data[4]; // index is machine dependant!
...

// cast
float *fptr = (float *)data;
printf ("%f\n",*fptr);

Из ваших правок, perhap, вы должны просто выбросить этот материал в struct:

struct packet_s {
   char byte0;
   float f1;
   float f2;
   ...
}

Тогда просто read (2) или что-то прямо в структуре. Этот метод обсуждался на SO ранее. Например:

0 голосов
/ 17 апреля 2009

При условии, что они уже в правильном формате:

float f = *((float*)(&received_data[1]));

Убедитесь, что вы не имеете в виду received_data[0]. Я оставил его как единое целое на случай, если у вас есть байт-заполнитель.

...