繁体   English   中英

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

[英]Does ANSI C support signed / unsigned bit fields?

将位字段限定为有符号/无符号是否有意义?

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

位域的类型必须是_Bool的合格或不合格版本,signed int,unsigned int或其他一些实现定义的类型。

是。 来自这里的一个例子:

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;

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

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

#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。

我认为安德鲁不是在谈论单位比特字段。 例如,4位字段:3位数字信息,一位符号。 尽管我承认无法提出这样的方案,但这完全是有道理的。

更新:我并不是说我无法想到多位位域的用途(在2400bps调制解调器时代一直使用它们来尽可能多地压缩数据以进行传输),但是我想不到用于带符号位字段的一种用法,特别是不是古朴的,明显的用法,对于读者来说,这将是一个“啊哈”时刻。

无疑,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;

埃里克

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

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

我目前正在仿真48位计算机,并尝试找出通过位域在64位“ long long”中使用48位是否合理……生成的代码与我所使用的相同做了所有的掩蔽,符号扩展等,但是它读起来好多了...

由于平台掩码可能会处理由于移位等引起的溢出,因此位掩码签名类型因平台硬件而异。

任何一半好的质量检查工具都会在使用时警告您。

如果对“位”进行了签名,则您的范围为-1、0、1,然后变成三进制数字。 我认为在此不适合使用标准缩写,但可以进行有趣的对话:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM