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

使用C中的#define获取常量浮点值的原始数据字节,c,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[] = {

我试图从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)
    };
#定义浮点到字节(值)\

(uint8_t)(value),(uint8_t)(value不能在
float
s上使用字节操作,因为它们没有标准化

如何做到这一点?注意:下面的所有方法都假设
float
为32位宽

指针

#define FLOAT_TO_BYTES(value) (*((unsigned char *) value)), (*(((unsigned char *) value) + 1)), (*(((unsigned char *) value) + 2)), (*(((unsigned char *) value) + 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]);

}
#包括
联合浮点字节{
浮动f;
字符b[大小(浮动)];
};
int main()
{
联合浮点_字节fb={1.1};
对于(int i=0;i使用自C99起可用的
联合的复合文字

不使用指针或移位。代码需要指定所需的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]);
  }
}

您真的希望预处理器为您计算这些字节吗?或者您可以将浮点作为
无符号字符的数组来访问,这样就足够了吗?如果是后者,那么像
常量double x=11.4;常量unsigned char*byteArray=(unsigned char*)(&x);
?或者您想要
sizeof(byteArray)这样的值怎么样
也应为
sizeof(双精度)请选择一种语言。C和C++是不同的语言,答案取决于你实际在哪个编码。我需要预处理器来计算字节,因为在实际实现中,BytErEx是KB大的一对,因此必须是一个Unt8t数组。为什么不覆盖“KB大的一对”呢?
uint8_t
数组带有一个“几KB大的”/4
float
数组作为一个
union
然后提供初始化为{11.4f,42.0f,3.14159f,…}`?不清楚,源代码是否需要以
float
s(如
11.4f、42.0f、3.14159f
或bytes
0x66、0x66、0x36、0x41、
)开头?我不确定指针变量是否调用未定义的行为。但是,
union
变量是明确允许的类型双关方式和首选方法。不确定,尽管你为什么添加了
packed
属性。它不是标准的,也没有必要。
packed
属性是基于我在操作系统开发方面的经验。它可能是没有必要的。我认为任何对
float
s的内存引用都应该是未定义的,即使对于操作系统开发来说也是毫无用处的。更好地转换为/from
uintN\u t
和shjift/mask进行编组。将优化留给编译器。在正常访问时,打包的
struct
s可能会较慢(如果CPU不支持像许多ARM一样的未对齐访问,则会慢得多),而(de)序列化通常只用于加载/存储数据。@Olaf I还为ARM编写代码。GCC将其优化为位移位内容(幸运的是:D)
#include <stdio.h>
int main()
{
    float f = 1.1;
    for(int i=0; i<sizeof(float);i++)
        printf("%hhx\n", ((char*)&f)[i]);

}
#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]);
}
#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