ANSI C 是否支持有符号/无符号位字段?

发布于 2024-07-07 11:09:32 字数 25 浏览 5 评论 0原文

将位域限定为有符号/无符号有意义吗?

Does it make sense to qualify bit fields as signed / unsigned?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

娇纵 2024-07-14 11:09:32

标准 (ISO/IEC 9899:1999) 的相关部分是 6.7.2.1 #4:

位字段应具有合格或不合格的类型
_Bool、signed int、unsigned int 或其他一些实现定义的版本
类型。

The relevant portion of the standard (ISO/IEC 9899:1999) is 6.7.2.1 #4:

A bit-field shall have a type that is a qualified or unqualified
version of _Bool, signed int, unsigned int, or some other implementation-defined
type.

清眉祭 2024-07-14 11:09:32

是的。 来自此处的示例:

struct {
  /* field 4 bits wide */
  unsigned field1 :4;
  /*
   * unnamed 3 bit field
   * unnamed fields allow for padding
   */
  unsigned        :3;
  /*
   * one-bit field
   * can only be 0 or -1 in two's complement!
   */
  signed field2   :1;
  /* align next field on a storage unit */
  unsigned        :0;
  unsigned field3 :6;
}full_of_fields;

只有您知道它在您的项目中是否有意义; 通常,如果该字段可以有意义地为负值,则它适用于具有多于一位的字段。

Yes. An example from here:

struct {
  /* field 4 bits wide */
  unsigned field1 :4;
  /*
   * unnamed 3 bit field
   * unnamed fields allow for padding
   */
  unsigned        :3;
  /*
   * one-bit field
   * can only be 0 or -1 in two's complement!
   */
  signed field2   :1;
  /* align next field on a storage unit */
  unsigned        :0;
  unsigned field3 :6;
}full_of_fields;

Only you know if it makes sense in your projects; typically, it does for fields with more than one bit, if the field can meaningfully be negative.

薄荷港 2024-07-14 11:09:32

将变量限定为有符号或无符号非常重要。 编译器需要知道在比较和转换期间如何处理变量。 检查此代码的输出:

#include <stdio.h>

typedef struct
{
    signed s : 1;
    unsigned u : 1;
} BitStruct;

int main(void)
{
    BitStruct x;

    x.s = 1;
    x.u = 1;

    printf("s: %d \t u: %d\r\n", x.s, x.u);
    printf("s>0: %d \t u>0: %d\r\n", x.s > 0, x.u > 0);

    return 0;
}

输出:

s: -1    u: 1
s>0: 0   u>0: 1

编译器使用单个位(1 或 0)存储变量。对于有符号变量,最高有效位确定符号(高位被视为负数)。 因此,有符号变量虽然以二进制形式存储为 1,但会被解释为负数。

扩展一下这个主题,无符号两位数的范围是 0 到 3,而有符号两位数的范围是 -2 到 1。

It's very important to qualify your variables as signed or unsigned. The compiler needs to know how to treat your variables during comparisons and casting. Examine the output of this code:

#include <stdio.h>

typedef struct
{
    signed s : 1;
    unsigned u : 1;
} BitStruct;

int main(void)
{
    BitStruct x;

    x.s = 1;
    x.u = 1;

    printf("s: %d \t u: %d\r\n", x.s, x.u);
    printf("s>0: %d \t u>0: %d\r\n", x.s > 0, x.u > 0);

    return 0;
}

Output:

s: -1    u: 1
s>0: 0   u>0: 1

The compiler stores the variable using a single bit, 1 or 0. For signed variables, the most significant bit determines the sign (high is treated negative). Thus, the signed variable, while it gets stored as 1 in binary, it gets interpreted as negative one.

Expanding on this topic, an unsigned two bit number has a range of 0 to 3, while a signed two bit number has a range of -2 to 1.

总攻大人 2024-07-14 11:09:32

是的,它可以。 C 位字段本质上只是有限范围的整数。 通常,硬件接口将位打包在一起,某些控制可以从 -8 到 7,在这种情况下,您确实需要一个有符号的位字段,或者从 0 到 15,在这种情况下,您需要一个无符号位 -场地。

Yes, it can. C bit-fields are essentially just limited-range integers. Frequently hardware interfaces pack bits together in such away that some control can go from, say, -8 to 7, in which case you do want a signed bit-field, or from 0 to 15, in which case you want an unsigned bit-field.

森林迷了鹿 2024-07-14 11:09:32

我不认为安德鲁在谈论单位位字段。 例如,4 位字段:3 位数字信息,1 位符号。 这完全有道理,尽管我承认我无法凭空想象出这样的场景。

更新:我并不是说我无法想到多位位字段的用途(在 2400bps 调制解调器时代一直使用它们来尽可能压缩数据以进行传输),但我无法认为有符号位域的使用,尤其是不是一种古怪、明显的、会让读者“顿悟”的时刻。

I don't think Andrew is talking about single-bit bit fields. For example, 4-bit fields: 3 bits of numerical information, one bit for sign. This can entirely make sense, though I admit to not being able to come up with such a scenario off the top of my head.

Update: I'm not saying I can't think of a use for multi-bit bit fields (having used them all the time back in 2400bps modem days to compress data as much as possible for transmission), but I can't think of a use for signed bit fields, especially not a quaint, obvious one that would be an "aha" moment for readers.

最丧也最甜 2024-07-14 11:09:32

毫无疑问,ANSI-C 提供了有符号和无符号位字段。 这是必需的。 这也是为 IEEE-754 浮点类型 [[1][5][10]]、[[1][8][23]] 和 [[1][10][53] 编写调试器覆盖的一部分]。 这对于此类数据的机器类型或网络转换很有用,或者在通过链接发送之前检查双精度(64 位用于数学)到半精度(16 位用于压缩)的转换,例如视频卡纹理。

// Fields need to be reordered based on machine/compiler endian orientation

typedef union _DebugFloat {
   float f;
   unsigned long u;
   struct _Fields {
        signed   s :  1;
        unsigned e :  8;
        unsigned m : 23;
      } fields; 
   } DebugFloat;

埃里克

Most certainly ANSI-C provides for signed and unsigned bit fields. It is required. This is also part of writing debugger overlays for IEEE-754 floating point types [[1][5][10]], [[1][8][23]], and [[1][10][53]]. This is useful in machine type or network translations of such data, or checking conversions double (64 bits for math) to half precision (16 bits for compression) before sending over a link, like video card textures.

// Fields need to be reordered based on machine/compiler endian orientation

typedef union _DebugFloat {
   float f;
   unsigned long u;
   struct _Fields {
        signed   s :  1;
        unsigned e :  8;
        unsigned m : 23;
      } fields; 
   } DebugFloat;

Eric

暮年 2024-07-14 11:09:32

有符号位域有用的地方之一是在仿真中,其中仿真机器的位少于默认字。

我目前正在考虑模拟 48 位机器,并试图弄清楚通过位域使用 64 位“long long”中的 48 位是否合理...生成的代码将与我相同明确地做了所有的掩码、符号扩展等,但它读起来会好得多......

One place where signed bitfields are useful is in emulation, where the emulated machine has fewer bits than your default word.

I'm currently looking at emulating a 48-bit machine and am trying to work out if it's reasonable to use 48 bits out of a 64-bit "long long" via bitfields... the generated code would be the same as if I did all the masking, sign-extending etc explicitly but it would read a lot better...

吃颗糖壮壮胆 2024-07-14 11:09:32

位屏蔽签名类型因平台硬件而异,因为它如何处理移位等溢出。

任何半好的 QA 工具都会故意警告此类使用。

Bit masking signed types varies from platform hardware to platform hardware due to how it may deal with an overflow from a shift etc.

Any half good QA tool will warn knowingly of such usage.

甜宝宝 2024-07-14 11:09:32

如果一个“位”被签名,那么你的范围是-1,0,1,然后它变成一个三进制数字。 我认为标准缩写不适合这里,但可以进行有趣的对话:)

if a 'bit' is signed, then you have a range of -1, 0, 1, which then becomes a ternary digit. I don't think the standard abbreviation for that would be suitable here, but makes for interesting conversations :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文