2016-03-17 67 views
4

我有一些位域:如何將signed int轉換爲15位的位域?

int somefield : 15; 

我想一個int轉換爲15位(可以是正或負)。

有效地做到這一點的最佳做法是什麼?

+2

將int分配給位域?它可能是實現定義的,但這對你來說是位域。 – EOF

+0

完全按照我做的方式,但編譯器報告錯誤(在Visual Studio中),但在其他機器上,它是OK(emacs + gcc)....所以它是依賴於機器,我試圖做到這一點獨立....(但是所有的機器都是LSB) – mibo6700

+1

如果位域是無符號的,如果你嘗試給它分配的int值是負值,你想要發生什麼? –

回答

3

我試圖將int轉換爲15位(可以是正數或負數)。有效地做到這一點的最佳做法是什麼?

如果要將int轉換爲15位有符號整數的範圍內,請使用下面的代碼。因爲這是C規範中的一個地方,所以不要使用int而不使用signed來定義位字段,這是非常重要的。沒有signedint位字段可以實現爲unsigned。它是實現定義的。

signed int somefield:15; 
... 
x.somefield = 12345; 
int y = x.somefield; 

如果int轉換可能比外面15位有符號整數的範圍內,最好使用unsigned場有便攜一致定義的行爲。目前還不清楚當int超出範圍時,OP想要存儲什麼價值。如果需要恢復標誌,可能需要一些額外的代碼。根據編碼需要,寫入時不需要額外的開銷,並且可能會有開銷。

unsigned somefield:15; 
... 
x.somefield = 123456; 

x.somefield = -1; 
int y = x.somefield >= 0x4000 ? x.somefield - 0x8000 : x.somefield; 

或者,如果要分配的值可能位於位域範圍之外,請確保分配不會發生。寫作時額外的開銷,沒有閱讀。

signed int somefield 15; 
... 
if (i >= INT15_MIN && i <= INT15_MAX) x.somefield = i; 
else TBD(); 

int y = x.somefield; 
+1

分配給一個符號類型不能代表值是*不*不確定。它是實現定義的。 – EOF

0

chux,非常感謝! 我發現了另一種選擇,它看起來很簡單,太:

typedef struct { 
    unsigned int firstletter: 5; 
    unsigned int secondletter: 5; 
    unsigned int thirdletter: 5; 
    } data_in_32_format; 

typedef struct { 
    unsigned int somedata: 15; 
    } data; 

typedef union { 
    data_in_32_format; 
    data; 
    } common_data; 

所以,當我在寫數據本身,我寫的:

common_data entry; 
entry.data = getint_in_decimal_format; 

比我「M印刷它在32格式:

print32("%c%c%c\n", entry.data_in_32_format.thirdletter 
        , entry.data_in_32_format.secondletter 
        , entry.data_in_32_format.firstletter); 

引起我需要將其轉換到先前的前正確CHAR(0-9 =>號,> 9 - 字母,所以在ASCII它是需要是55表示32位格式正確(A爲10等)。