如何将 signed int 转换为 15 位位域?
How to cast signed int to 15 bit bit-field?
我有一些位域:
int somefield : 15;
我正在尝试将 int 转换为 15 位(可以是正数或负数)。
有效执行此操作的最佳做法是什么?
I'm trying to convert an int to 15 bit (can be positive or negative). What is the best practice to do it efficiently?
如果要转换的int
是15位有符号整数范围内的,简单使用下面的代码。重要的是不要在没有 signed
的情况下使用 int
来定义位域,因为这是 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;
或者,如果要分配的值可能超出位域范围,请确保分配不会发生。额外的写入开销和 none 读取开销。
signed int somefield 15;
...
if (i >= INT15_MIN && i <= INT15_MAX) x.somefield = i;
else TBD();
int y = x.somefield;
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;
比起我以 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等等)。
我有一些位域:
int somefield : 15;
我正在尝试将 int 转换为 15 位(可以是正数或负数)。
有效执行此操作的最佳做法是什么?
I'm trying to convert an int to 15 bit (can be positive or negative). What is the best practice to do it efficiently?
如果要转换的int
是15位有符号整数范围内的,简单使用下面的代码。重要的是不要在没有 signed
的情况下使用 int
来定义位域,因为这是 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;
或者,如果要分配的值可能超出位域范围,请确保分配不会发生。额外的写入开销和 none 读取开销。
signed int somefield 15;
...
if (i >= INT15_MIN && i <= INT15_MAX) x.somefield = i;
else TBD();
int y = x.somefield;
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;
比起我以 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等等)。