提问人:Hermit 提问时间:11/1/2023 最后编辑:Hermit 更新时间:11/1/2023 访问量:119
使用联合操作浮点位:查找适合浮点数的正确 uint 类型
Manipulating float bits using unions: Finding the correct uint type that fits the float
问:
在 C 语言中,我看到这段代码被用作操作浮点数的一种方式,直到位:
union {
uint32_t bits;
float value;
}
通过定义这种类型的变量,可以在侧面执行按位运算,同时计算浮点值本身,而浮点值本身又可以打印并在表达式中使用。var.bits
var.value
但是,代码依赖于宽度与大小匹配的事实。虽然通常是这种情况,但我很好奇如何在没有这种假设的情况下实现此代码,即它根据浮点大小选择正确的固定宽度整数。float
unit32_t
我想到的一种方法是使用一堆语句,并通过比较和宽度常量进行分支,例如:if
sizeof(float)
stdint.h
if (sizeof(float) == sizeof(uint32_t)) {
// Define the union with float and uint32_t and do the manipulations ...
} else if (sizeof(float) == sizeof(uint64_t)) {
// Define the union with float and uint64_t and do the manipulations ...
}
else ...
这将起作用,但必须在每个 if 语句中重复代码。我更喜欢在类型声明本身之后全局声明和初始化变量本身,如下所示:
union {
uint32_t bits;
float val;
} var = {UINTMAX_C(1)};
因此,该分支需要在预处理级别静态发生,并且在 .sizeof
#if
有没有另一种方法可以为浮点数找到正确的固定宽度整数类型?
答:
1赞
chux - Reinstate Monica
11/1/2023
#1
这不是一个完全有效的解决方案,但是一个开始:根据 .
也许用其他属性进行优化。float
FLT_XXX
#include <assert.h>
#include <float.h>
#include <stdint.h>
#if FLT_MANT_DIG <= 24 + 2
typedef uint32_t uint_flt;
#elif FLT_MANT_DIG <= 53 + 4
typedef uint64_t uint_flt;
#else
#error TBD code
#endif
// If we got it wrong, stop the compilation.
static_assert(sizeof(float) == sizeof(uint_flt), "TBD code");
请注意,浮点类型,甚至 ,可能是 128 位,并且没有匹配的整数,当然那么宽。float
请注意,FP 和整数技巧的整个过程都受到阻碍,因为两者的字节序肯定不相同。机器就是这样建造的。因此,使用某个整数常量进行初始化并不像人们所希望的那样可移植。union
相反,请重新编写代码以使用字节数组。
union {
float value;
unsigned char bits[sizeof(float)];
} x;
使用 here 的此类代码通常表明了实现更高级别编码目标的错误方法。
考虑陈述更高层次的目标。union
评论
0赞
Lundin
11/1/2023
我认为我们可以放心地假设这一点,如果在同一个 CPU+FPU 上运行,则具有相同的字节数。float
uint32_t
0赞
chux - Reinstate Monica
11/1/2023
@Lundin 安全 - 是的,有点,但是......C 没有指定相同的字节序,并且存在历史反例。IMO,这种混合匹配的字节序使平台成为恐龙,但更好的代码会使用 a 来测试相同的字节序,而不是赤裸裸地假设相同。此外,我仍然想知道OP更高层次的关注。static_assertion()
0赞
Lundin
11/1/2023
C 没有指定它,因为它不是 C 的事。由于 C 没有指定它,因此由应用程序程序员以适当的方式处理它。
0赞
chux - Reinstate Monica
11/1/2023
@Lundin C23/24 正在冒险进入字节序领域,至少在整数方面是这样,使用 .看看一旦它在这里,它是如何发挥作用的。__STDC_ENDIAN_BIG__, __STDC_ENDIAN_LITTLE__, __STDC_ENDIAN_NATIVE__
0赞
Lundin
11/1/2023
这些只是功能,省去了你编写一个小宏来检查它的麻烦 - C 仍然没有规定 CPU 具有哪个字节。 不过,确实提供了各种奇怪的、据说是便携式的功能。stdbit.h
下一个:解决浮点序列管理中的精度挑战
评论
float
(u)intN_t
sizeof(uint32_t) == sizeof(float)