我有一些位域:
int somefield : 15;
我试图将int转换为15位(可以是正数或负数)。
有效地完成这项工作的最佳做法是什么?
答案 0 :(得分:4)
我正在尝试将int转换为15位(可以是正数或负数)。有效地做到这一点的最佳做法是什么?
如果要转换的int
在15位有符号整数的范围内,请使用以下代码。重要的是不要在没有int
的情况下使用signed
来定义位域,因为这是C规范中的一个位置,它会有所不同。如果没有signed
,int
位字段可以实现为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 :(得分:0)
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;
比我用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 =&gt;数字,&gt; 9 - 字母,所以在ASCII中需要+55才能正确表示32位格式(A代表10)等等。)。