结构到IEEE754

时间:2012-02-15 23:13:35

标签: c ieee-754

我的问题涉及IEEE 754单精度数字。 假设我有一个结构:

typedef struct __ieee754
{ 
   int sign;
   int exponent;
   int mantissa;
} IEEE754,*pIEEE754;

我可以将其转换为单精度(1-8-23浮点数)吗?我正在使用C.

3 个答案:

答案 0 :(得分:4)

假设您的实现使用float的IEEE 754单精度数字,这样的事情应该可行

struct __ieee754 f;
/* set f to something valid */
float x = f.sign * f.mantissa * pow(2, f.exponent);

答案 1 :(得分:3)

假设32位unsigned int和IEEE-754单精度float类型:

union bla {
    unsigned int a;
    float b;
};

union bla num = {
        (((unsigned int) f.sign & 1) << 31)
      | (((unsigned int) f.exponent & 0xFF) << 23)
      | ( (unsigned int) f.mantissa & 0x7FFFFF); 
};

printf("%f\n", num.b)

答案 2 :(得分:3)

前两个答案中的一个必须是错误的 - 因为问题未明确。我们需要知道结构是否包含IEEE float组件的二进制表示,或者它是否包含数字定义。

基于它们是整数的事实,第一个更有可能:-4.2将表示为{1,0x81,0x066666}0xC0866666。在这种情况下,@ ouah的答案是正确的,@ pmg将给出2.85e44。

另一方面,为了使@pmg的代码正确,-4.2的结构必须存储为{-1,-21,0x433333}。然后应用@ ouah算法给出0xF5C33333,当解释为IEEE浮点数时为-4.9489e32。

如果我们假设您使用的是第一个表示形式,那么就有一个非便携式处理器技巧可以简化您的代码。将结构重新定义为联合,如下所示。

union flt  {  
    struct ieee754 {
       unsigned int mantissa:23;
       unsigned int exponent:8;
       unsigned int sign:1;
    } raw;
    float f;
 }

(您可能需要根据您的处理程序颠倒参数的顺序 - 并确保打包是正确的 - 这是非便携式部分)

现在你的代码可以作为位直接写入内存并将其作为浮点数读回:

  union flt num;
  num.raw.sign = 1;
  num.raw.exponent = 129;
  num.raw.mantissa = 0x66666;
  printf("%f", num.f);  //prints 4.2