使用C中的#define获取常量浮点值的原始数据字节
我试图从C中的常量浮点中检索原始数据字节。这样做是为了创建一个可读的常量字节数组。这可以在下面看到使用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[] = {
#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大的”/4float
数组作为一个union
然后提供初始化为{11.4f,42.0f,3.14159f,…}`?不清楚,源代码是否需要以float
s(如11.4f、42.0f、3.14159f
或bytes0x66、0x66、0x36、0x41、
)开头?我不确定指针变量是否调用未定义的行为。但是,union
变量是明确允许的类型双关方式和首选方法。不确定,尽管你为什么添加了packed
属性。它不是标准的,也没有必要。packed
属性是基于我在操作系统开发方面的经验。它可能是没有必要的。我认为任何对float
s的内存引用都应该是未定义的,即使对于操作系统开发来说也是毫无用处的。更好地转换为/fromuintN\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