使用联合操作浮点位:查找适合浮点的正确 uint 类型

问题描述 投票:0回答:1

在 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))
    typedef uint32_t CorrectInt;
else if (sizeof(float) == sizeof(uint64_t))
    typedef uint64_t CorrectInt;
else ...

这段代码只有编译后才能运行。联合类型可以在全局范围内定义,但现在变量本身必须在本地声明。我更喜欢在类型声明本身之后全局声明并初始化变量本身,如下所示:

union {
    uint32_t bits;
    float val;
} var = {UINTMAX_C(1)};

所以分支方法行不通。

还有另一种方法可以为浮点数找到正确的固定宽度整数类型吗?

c floating-point bit-manipulation union
1个回答
0
投票

不是一个完整的解决方案,但却是一个开始:根据

float
的有效位计数来引导代码。
也许可以使用其他
FLT_XXX
属性进行优化。

#include <assert.h>
#include <float.h>
#include <stdint.h>

#if FLT_MANT_DIG <= 28
  typedef uint32_t flt_int;
#elif FLT_MANT_DIG <= 28*2
  typedef uint32_t flt_int;
#elif FLT_MANT_DIG <= 28*4
  typedef uint64_t flt_int;
#else
  #error TBD code
#endif

// If we got it wrong, stop the compilation.
static_assert(sizeof(float) == sizeof(flt_int), "TBD code");
© www.soinside.com 2019 - 2024. All rights reserved.