簡體   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