IEEE 754算术,4字节(32位)

时间:2012-01-31 14:51:08

标签: c coding-style floating-point byte ieee-754

我编写了这段代码,用于对4字节字符串进行IEEE 754浮点运算。

它接收字节,将它们转换为二进制,并使用二进制我得到符号,指数和尾数,然后进行计算。

这一切都适用于perfectl,0xDEADBEEF给了我6259853398707798016,真正的答案是6.259853398707798016E18,现在这些是相同的值,我在我正在使用的项目中没有任何这么大的值,所有其他较小的值都放小数在正确的地方。

这是我的代码:     float calcByteValue(uint8_t data []){        int i;        int j = 0;        int index;        int sign,exp;        浮动仆人;

   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;
}

现在,我的老师告诉我,有一种更容易的方法,我可以接受字节流,并把它变成一个浮点数,它应该工作。我试着这样做,但如果我的生活依赖于它,就无法弄明白。

我不是要求你为我做作业,我已经完成并且正在工作,但我只需要知道我是否能够以不同方式/更容易/更有效地完成它。

编辑:我需要处理几个特殊情况,但是如果指数全部为零,那就等等。易于实施。

4 个答案:

答案 0 :(得分:1)

老师可能记住了这一点:

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

对于有关字节序的问题,我会反对它。但如果你的老师想要它,他就会拥有它。

答案 1 :(得分:0)

我认为你想要一个联合 - 只需创建一个联合,其中一个成员是一个4个字符的数组,另一个是浮点数。写第一个,然后读第二个。

答案 2 :(得分:0)

查看代码的作用,然后“4字节字符串”看起来已经包含32位浮点数的二进制表示,因此它已存在于大端字节中由data指定的地址的内存中顺序。

您可以将数组data转换为浮点指针并取消引用(如果您可以假设您运行的系统是大端,并且数据将正确对齐平台上的浮点类型)

或者,如果您需要更多控制(例如更改字节顺序或确保对齐),您可以使用uint8_t数组和float的并集来查看类型双关语。将字节复制到union的uint8_t数组中,然后读取float成员。

答案 3 :(得分:0)

这是我的工作代码:

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

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

    cout << f << endl;
    return 0;