gpt4 book ai didi

从 IEEE754 浮点格式读取字节的正确方法

转载 作者:行者123 更新时间:2023-12-02 17:06:21 30 4
gpt4 key购买 nike

我有一个要求,我需要读取 单精度 IEEE754 float 表示的 4 个原始字节,以便在没有任何修改的情况下在串行端口上发送。我只是想问一下提取以下字节的正确方法是什么:

1.) 创建 union ,例如:

typedef union {
float f;
uint8_t bytes[4];
struct {
uint32_t mantissa : 23;
uint32_t exponent : 8;
uint32_t sign : 1;
};
} FloatingPointIEEE754_t ;

然后在写入浮点变量 f 后只读取 bytes[] 数组?

2.) 或者,通过使 uint32_t 类型指针指向 float 变量的函数提取字节,然后通过掩码

uint32_t extractBitsFloat(float numToExtFrom, uint8_t numOfBits, uint8_t bitPosStartLSB){
uint32_t *p = &numToExtFrom;
/* validate the inputs */
if ((numOfBits > 32) || (bitPosStartLSB > 31)) return NULL;
/* build the mask */
uint32_t mask = ((1 << numOfBits) - 1) << bitPosStartLSB;
return ((*p & mask) >> bitPosStartLSB);
}

调用方式如下:

valF = -4.235;
byte0 = extractBitsFloat(valF, 8, 0);
byte1 = extractBitsFloat(valF, 8, 8);
byte2 = extractBitsFloat(valF, 8, 16);
byte3 = extractBitsFloat(valF, 8, 24);

如果您认为上述两种方法都是错误的,请告诉我正确的方法!

最佳答案

首先,我假设您正在专门为一个平台编写代码,其中 float 实际上 以 IEEE754 单个 表示。您不能一般认为这是理所当然的,因此您的代码将无法移植到所有平台。

那么,union 方法是正确的方法。但是不要添加这个位域成员!无法保证位的排列方式,因此您可能会访问错误的位。只需这样做:

typedef union {
float f;
uint8_t bytes[4];
} FloatingPointIEEE754;

此外,不要为您自己的类型添加 _t 后缀。在 POSIX 系统上,这是为实现保留的,因此最好始终避免它。

不使用union,通过char 指针访问字节也可以:

unsigned char *rep = (unsigned char *)&f;
// access rep[0] to rep[3]

请注意,在这两种情况下,您都在访问内存中的表示形式,这意味着您必须注意 endianness你的机器。


您的第二个选项不正确,它违反了严格的别名规则。简而言之,不允许通过不兼容类型的指针访问对象,char 指针是访问表示的显式异常(exception)。确切的规则写在 6.5 p7 of N1570 中,C11 标准的最新草案。

关于从 IEEE754 浮点格式读取字节的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51607828/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com