Арифметика IEEE 754 на 4 байта (32 бита) - PullRequest
0 голосов
/ 31 января 2012

Я написал этот код для выполнения арифметики IEEE 754 с 4-байтовой строкой.

Он принимает байты, преобразует их в двоичные, а с двоичными данными я получаю знак, экспоненту и мантиссу изатем сделайте расчет.

Все это работает примерно на perfectl, 0xDEADBEEF дает мне 6259853398707798016, а истинный ответ - 6.259853398707798016E18, теперь это те же значения, и у меня не будет ничего такого большого в проекте, с которым я работаювсе остальные меньшие значения помещают десятичное число в правильное место.

Вот мой код: float calcByteValue (uint8_t data []) {int i;int j = 0;int index;int знак, exp;float mant;

   char bits[8] = {0};
   int *binary = malloc(32*sizeof *binary);
   for (index = 0;index < 4;index++) {
      for (i = 0;i < 8;i++,j++) {
         bits[i] = (data[index] >> 7-i) & 0x01;
         if (bits[i] == 1) {
            binary[j] = 1;
         } else {
            binary[j] = 0;
         }
      }
      printf("\nindex(%d)\n", index);
   }

   sign = getSign(&(binary[0]));
   mant = getMant(&(binary[0]));
   exp = getExp(&(binary[0]));

   printf("\nBinary: ");
   for (i = 0;i < 32;i++)
      printf("%d", binary[i]);
   printf("\nsign:%d, exp:%d, mant:%f\n",sign, exp, mant);

   float f = pow(-1.0, sign) * mant * pow(2,exp);
   printf("\n%f\n", f);
   return f;
}

//-------------------------------------------------------------------

int getSign(int *bin) {
   return bin[0];
}

int getExp (int *bin) {
     int expInt, i, b, sum;
     int exp = 0;

     for (i = 0;i < 8;i++) {
        b = 1;
        b = b<<(7-i);
        if (bin[i+1] == 1)
           exp += bin[i+1] * b;
     }

     return exp-127;

}

float getMant(int *bin) {
   int i,j;
   float b;
   float m;
   int manBin[24] = {0};
   manBin[0] = 1;
   for (i = 1,j=9;j < 32;i++,j++) {
       manBin[i] = bin[j];
       printf("%d",manBin[i]);
   }
   for (i = 0;i < 24;i++) {
      m += manBin[i] * pow(2,-i);;
   }
   return m;
}

Теперь мой учитель сказал мне, что есть гораздо более простой способ, где я могу просто взять поток байтов и превратить его в float, и он должен работать.Я пытался сделать это таким образом, но не мог понять, если моя жизнь зависела от этого.

Я не прошу вас делать мою домашнюю работу для меня, я сделал это и работаю, но мне просто нужноЗнайте, если бы я мог сделать это по-другому / проще / эффективнее.

РЕДАКТИРОВАТЬ: есть пара особых случаев, которые мне нужно обработать, но это просто такие вещи, как если показатель степени равен нулю, бла-бла-бла-бла.Простота реализации.

Ответы [ 4 ]

1 голос
/ 31 января 2012

Учитель, вероятно, имел это в виду:

char * str; // your deadbeef
float x;
memcpy(&x, str, sizeof(float));

Я бы советовал против этого, для вопросов с порядком байтов. Но если твой учитель этого захочет, он получит это.

0 голосов
/ 01 февраля 2012

Вот мой рабочий код:

    unsigned char val[4] = {0, 0, 0xc8, 0x41};
    cout << val << endl;

    cout << "--------------------------------------------" << endl;
    float f = *(float*)&val;

    cout << f << endl;
    return 0;
0 голосов
/ 31 января 2012

Если посмотреть на то, что делает ваш код, то «4-байтовая строка» выглядит так, как будто она уже содержит двоичное представление 32-разрядного числа с плавающей запятой, поэтому она уже существует в памяти по адресу, указанному data в байтовом порядке с прямым порядком байтов.

Вы, вероятно, могли бы привести массив data к указателю с плавающей точкой и разыменовать его (если вы можете предположить, что система, на которой вы работаете, имеет обратный порядок байтов и эти данные будут правильно выровнены для типа с плавающей точкой на вашей платформе).

В качестве альтернативы, если вам нужно больше контроля (например, для изменения порядка байтов или обеспечения выравнивания), вы можете посмотреть на тип punning, используя объединение массива uint8_t и float. Скопируйте байты в массив uint8_t вашего объединения, а затем прочитайте член с плавающей точкой.

0 голосов
/ 31 января 2012

Я думаю, что вы хотите объединение - просто создайте объединение, где один член представляет собой массив из 4 символов, а другой - число с плавающей точкой. Напишите первое, затем прочитайте второе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...