使用C中的#define获取常量浮点值的原始数据字节

时间:2017-01-25 21:32:22

标签: c

我试图从C中的常量浮点数中检索原始数据字节。这样做是为了创建一个可读的常量字节数组。这可以在下面看到。

    #define FLOAT_TO_BYTES(value) \
        (uint8_t)(value),       (uint8_t)(value << 8), \
        (uint8_t)(value << 16), (uint8_t)(value << 24)

    const uint8_t byteArray[] = {
         FLOAT_TO_BYTES(11.4)
    };

问题是我不能使用指针或任何类型的代码块。我知道上面的内容不起作用,因为你不能移动浮点值。我曾经尝试过使用工会,但也无法让它工作。任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:3)

以下是如何使用union获取字节:

#include <stdio.h>

union float_bytes{
    float f; 
    char  b[sizeof(float)];
};

int main()
{
    union float_bytes fb = { 1.1 };
    for(int i=0; i<sizeof(float);i++)
        printf("%hhx\n", fb.b[i]);

}

您也可以这样做:

#include <stdio.h>
int main()
{
    float f = 1.1;
    for(int i=0; i<sizeof(float);i++)
        printf("%hhx\n", ((char*)&f)[i]);

}

始终允许通过字符指针检查任何内容。

如果你真的想,你可以将演员表(char *)放到一个宏中 并传入一个浮点指针,或者您可以在宏中创建一个复合文字临时值,以避免显式浮点变量:

#include <stdio.h>

#define FLOAT_BYTES(Float) ((char*)(&(float){Float}))
int main()
{
    for(int i=0; i<sizeof(float);i++)
        printf("%hhx\n", FLOAT_BYTES(1.1)[i]);
}

(复合文字的生命周期是其最近的封闭块的生命周期。)

答案 1 :(得分:0)

您不能在float上使用字节操作,因为它们不是标准化的。

怎么做? 注意:以下所有方法都假设float为32位宽。

指针

#define FLOAT_TO_BYTES(value) (*((unsigned char *) value)), (*(((unsigned char *) value) + 1)), (*(((unsigned char *) value) + 2)), (*(((unsigned char *) value) + 3))

联盟

typedef union
{
  float f;
  unsigned char chars[4];
} __attribute__ ((packed)) floatunion;

// I am lazy:
#define FLOAT_TO_BYTES(value) FLOAT_TO_BYTES0 ((floatunion *) &value)
#define fLOAT_TO_BYTES0(value) value->chars[0], value->chars[1], value->chars[2], value->chars[3]

答案 2 :(得分:0)

使用自{C99以来可用的union复合文字

不使用指针或移位。代码需要指定所需的float字节和顺序。

#define FLOAT_TO_BYTE(float_value, index) \
    (( \
    (union { float f; uint8_t u8[sizeof (float)]; }) {(float_value)} \
    ).u8[(index)])

// size sensitive code - assume sizeof (float) == 4
#define FLOAT_TO_BYTES(float_value) \
    FLOAT_TO_BYTE((float_value), 0), FLOAT_TO_BYTE((float_value), 1), \
    FLOAT_TO_BYTE((float_value), 2), FLOAT_TO_BYTE((float_value), 3)

int main(void) {
  const uint8_t byteArray[] = { 
      42,
      FLOAT_TO_BYTE(11.4, 0),
      FLOAT_TO_BYTE(11.4, 1),
      FLOAT_TO_BYTE(11.4, 2),
      FLOAT_TO_BYTE(11.4, 3),
      42,
      FLOAT_TO_BYTES(11.4)
  };
  for (unsigned i=0; i<sizeof byteArray; i++) {
    printf("%u %u\n", i, 1u*byteArray[i]);
  }
}

输出

0 42
1 102
2 102
3 54
4 65
5 42
6 102
7 102
8 54
9 65