0

我有以下结构:

struct
{
   int a:4;
   int b:7;
   int c:21;
} example;

我想在 C++ 中将 a 和 b 组合成一个整数 d。例如,我希望 a 的位值位于 b 的位值的左侧,以便形成整数 d。这是如何在 C++ 中实现的?

例子:

一个= 1001

b = 1010101

我想要 int d = 10011010101 xxxxxxxxxxxxxxxxxxxxx

其中 x 可以是之前属于 d 的 21 位。我希望将 a 和 b 的值分别放在位位置 0-3 和 4-10 中,因为 a 占据结构“示例”中的前 4 位,而 b 占据接下来的 7 位。

我感到困惑的部分是变量 a 和变量 b 在最高有效位都有一个“符号”位。这会影响结果吗?变量 a 和变量 b 中的所有位是否都用于整数 d 的最终结果?整数 d 看起来像变量 a 的位和变量 b 的位的串联吗?

谢谢

4

1 回答 1

2

请注意,int位域是有符号还是无符号是实现定义的。C++ 标准是这样说的,而 C 标准用不同的措辞实现了相同的最终结果:

ISO/IEC 14882:2011 — C++

§7.1.6.2 简单类型说明符

¶3 ... [注意:char类型和某些位域(9.6)的对象是否表示为有符号或无符号数量是实现定义的。说明signed符强制char对对象和位域进行签名;它在其他情况下是多余的。——尾注]

§9.6 位域

¶3 ...位字段应具有整数或枚举类型(3.9.1)。普通(既没有显式签名也没有无符号)、、、、或char位字段是有符号还是无符号是实现定义的。shortintlonglong long

ISO/IEC 9899:2011 — C

§6.7.2.1 结构和联合说明符

¶10 位字段被解释为具有由指定位数组成的有符号或无符号整数类型。125)

125)如上面 6.7.2 所述,如果实际使用的类型说明符是 int 或定义为 int 的 typedef-name,那么位域是有符号还是无符号是实现定义的。

§6.7.2 类型说明符

¶5 ... 对于位域,说明符int指定与 相同的类型signed int还是与 . 相同的类型是实现定义的unsigned int

§6.7.2 的上下文表明int可以与short,long等结合使用,规则将适用;C++ 更清楚地说明了这一点。当然,plain 的签名char已经由实现定义。


无符号位域

如果位域的类型是无符号的,那么表达式相当简单:

int d = (example.a << 7) | example.b;

有符号位域

example.a如果这些值是有符号的,那么你需要进行一个主要的解释练习,决定如果是负数和正数应该是什么值example.b,反之亦然。在某种程度上,即使这些值都是负数或正数,也会出现问题。

假设example.a = 7;-example.b = 12;的值应该是d多少?可能相同的表达式适用,但您可能会争辩说最好少移动 1 个位置:

assert(example.a >= 0 && example.b >= 0);
int d = (example.a << 6) | example.b;      // Alternative interpretation

其他情况由您决定;这取决于您要对这些值进行的解释。例如:

int d = ((example.a & 0x0F) << 7) | (example.b & 0x7F);

这会强制将有符号值视为无符号值。这可能不是你所追求的。


修改后的问题

example.a = 1001     // binary

example.b = 1010101  // binary

d = 10011010101 xxxxxxxxxxxxxxxxxxxxx

其中 x 可以是之前属于 d 的 21 位。

为此,您需要:

  d = (d & 0x001FFFFF) | ((((example.a & 0x0F) << 7) | (example.b & 0x7F)) << 21);

您可能可以使用更少的括号;我不确定我会冒险这样做。

联盟

但是,使用此修订后的规范,您可能很想查看以下内容union

union u
{
    struct
    {
       int a:4;
       int b:7;
       int c:21;
    } y;
    int x;
} example;

但是,未指定位字段中位的布局int x;(它们可能是最高有效位在前或最低有效位在前),并且总是有关于“如果您访问联合中的值”的说法这不是分配给您的最后一个调用未定义的行为'。因此,您需要处理位字段的多个平台定义方面。事实上,这种难题通常意味着位域与一种特定类型的机器 (CPU) 以及编译器和操作系统密切相关。在您所追求的细节级别上,它们非常非常不便携。

于 2012-11-21T02:17:55.463 回答