c - 如何将 c 中的整数位字段连接成 uint64_t 整数?
问题描述
我在c中有一个这样的结构
struct RegisterStruct
{
uint64_t b_0 : 64;
uint64_t b_1 : 64;
uint64_t c_0 : 64;
uint64_t c_1 : 64;
uint64_t c_2 : 64;
uint64_t d_0 : 64;
uint64_t d_1 : 64;
};
我想将这些字段连接成一个uint64_t
整数。每个字段应占用给定数量的位,定义如下:
b_0: 4bits
b_1: 4bits
c_0: 8bits
c_1: 8bits
c_2: 8bits
d_1: 16bits
d_2: 16bits
结果应该是一个uint64_t
整数,其中包含连接的位字段(从b_0
到d_2
),每个位字段占用给定的位数。
这是我尝试过的,但我认为这个解决方案不正确:
struct RegisterStruct Register;
Register.b_0 = 8;
Register.b_1 = 8;
Register.c_0 = 128;
Register.c_1 = 128;
Register.c_2 = 128;
Register.d_0 = 32768;
Register.d_1 = 32768;
uint64_t reg_frame =Register.b_0<<60|Register.b_1<<56|Register.c_0<<48|Register.c_1<<40|Register.c_2<<32|Register.d_0<<16|Register.d_1;
解决方案
您可以将包含位字段的结构与完整的 64 位无符号整数放在一个联合中,如下所示:
union RegisterUnion
struct
{
uint64_t b_0 : 4;
uint64_t b_1 : 4;
uint64_t c_0 : 8;
uint64_t c_1 : 8;
uint64_t c_2 : 8;
uint64_t d_0 : 16;
uint64_t d_1 : 16;
};
uint64_t val;
};
上面的主要问题是它不便携。C 标准将位字段打包到其底层存储单元类型(uint64_t
在这种情况下)中的顺序保留为实现定义的决定。这与多字节整数中的字节排序完全分开,即小端字节序与大端字节序。
此外,uint64_t
可能不支持用作位字段的基本类型。只需要一个实现来支持类型的位字段成员_Bool
,signed int
和unsigned int
(或其合格版本)。根据C11 草案 6.7.2.1 第 5 段:
- 位域的类型应为 、 、 或其他一些实现定义的类型的合格或非
_Bool
合格signed int
版本unsigned int
。是否允许原子类型是实现定义的。
推荐阅读
- c# - 有没有办法调用正在运行的 WinForms 程序的方法并为另一个 WinForms 程序的方法设置参数?
- google-sheets - 根据从电子表格中另一个单元格中的值获得的引用获取单元格中的值
- spring-boot - Jenkins 未能执行目标 Maven 发布
- java - 无法访问 openapi-generator-cli.jar 文件
- amazon-web-services - AWS:在为实例指定安全组时,它的 ENI 是否在后台指定了安全组?
- ajax - QUnit 测试 AJAX 调用
- deep-learning - 我如何在 Julia 中创建一个包并开源它?
- flutter - 是否可以在移动应用程序中使用营销 API?
- php - PHP 获得与文本颜色白色兼容的随机颜色?
- c# - C# 开发人员命令提示符