我刚刚开始在 python 中使用 bitarray 包,并尝试从整数创建 bitarray 给了我非常令人困惑的结果:
>>> import bitarray
>>> bitarray.bitarray(5)
bitarray('01000')
>>> bitarray.bitarray(5)
bitarray('00010')
>>> bitarray.bitarray(5)
bitarray('00100')
>>> bitarray.bitarray(5)
bitarray('00110')
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么会发生这种情况?
另外:从 int 生成位数组的更好方法是什么?这是可行的,但是字符串转换似乎是一种奇怪的方法......
>>> bitarray.bitarray(bin(5)[2:])
bitarray('101')
Run Code Online (Sandbox Code Playgroud)
编辑:我最终切换到bitstring,它确实有一个从整数获取位串的简单方法:
>>> bitstring.BitArray(uint=5,length=6)
BitArray('0b000101')
Run Code Online (Sandbox Code Playgroud) 我有一个数字0x5423,我想提取 4 个值:
a = 0x5 # 15 downto 12
b = 0x42 # 11 downto 3
c = 0x3 # 3 downto 2
d = 0x00 # 1 downto 0
Run Code Online (Sandbox Code Playgroud)
我发现模块位串看起来很棒。不幸的是,由于未知的原因,这些位是从右侧开始编号的。
这很糟糕,因为如果添加一些像0xA5423我的提取这样的高位将不再起作用:
field = bitstrings.BitArray('0x5423')
a = field[0:4].uint
b = field[4:12].uint
c = field[12:14].uint
d = field[14:16].uint
Run Code Online (Sandbox Code Playgroud)
如何在不进行复杂算术操作的情况下正确提取位域,例如:
b = (a >> 4) & 0xFF
Run Code Online (Sandbox Code Playgroud)
理想情况下我会:
b = field.range(11, 4)
Run Code Online (Sandbox Code Playgroud) 结构和类
有offsetof宏和运算符。有没有办法获得位字段的类似功能,以便可以查询位字段成员的位偏移量和位大小?sizeof
可以sizeof使用 来模拟#define field_name_size n,但恐怕offsetof使用起来会变得太麻烦#define field_name_offset,因为那时似乎必须使用一些复杂的公式来考虑位字段中所有前面的成员。
在某些情况下,它可以使人们克服手动保持代码与位字段定义同步的需要,而这种需要很容易失败。
一个示例是对位字段成员的互锁写入,其中需要使用自定义函数来写入此类成员,因为编译器不提供此类功能。
此外,我了解编译器实现位字段布局的方式可能略有不同。此类宏/运算符的可用性也将减少该问题的影响。
我有一个包含多个位字段的结构,每个字段必须在长度为 14 位的“变量”中定义不同的内容,在该过程结束时我需要像二进制中的一个变量一样打印该结构,我找到了某种方法来创建另一个 14 位结构,像麝香一样使用它,它可以完成工作,但 valgrind 说 条件跳转或移动取决于未初始化的值 是否有更好的方法来打印它?仅8位示例,但不能使用char(实际需要14位)
#define MAX 8
typedef struct varNode{
unsigned int s1:2;
unsigned int s2:4;
unsigned int s3:2;
}var;
void printNode(var* node){
typedef struct {
unsigned data:MAX;
}mask;
mask temp={0};
temp.data=temp.data|((node->s1)|(node->s2<<2)|(node->s3<<6));
unsigned x;
x=1;
x=x<<(unsigned )(MAX-1);
while(x) {
if (temp.data & x )
printf("1");
else printf("0");
x>>=1;
}
printf("\n");
}
void main(){
var a={1,2,3};
printNode(&a);
}
Run Code Online (Sandbox Code Playgroud)
这里:
temp.data=temp.data|((node->s1)|(node->s2<<2)|(node->s3<<6));
Run Code Online (Sandbox Code Playgroud)
编译器警告我关于带有二元运算符的有符号整数操作数,无法理解为什么,节点中的所有字段都是无符号的
我正在使用 Visual Studio 2015 C/C++ 编译器编译一段 UEFI C 代码。
编译器针对的是IA32,而不是 X64 。
当使用“/O1”打开优化时,构建正常。
当使用“/Od”关闭优化时,构建会出现以下错误:
error LNK2001: unresolved external symbol __aullshr
Run Code Online (Sandbox Code Playgroud)
根据here,有一个解释为什么编译器可以隐式调用此类函数:
事实证明,该函数是Microsoft C/C++ 编译器显式调用的几个编译器支持函数之一。在这种情况下,只要 32 位编译器需要将两个 64 位整数相乘,就会调用此函数。EDK不与微软的库链接,也不提供此功能。
还有其他类似的功能吗?当然,还有几个用于 64 位除法、求余和移位的操作。
但根据这里:
...实现内部函数的编译器通常仅在程序请求优化时才启用它们 ...
那么,当我使用 ?? 显式关闭优化时,如何仍然调用此类函数/Od?
看来我对这个__aullshr功能的理解是错误的。
它不是编译器内部函数。根据here,原来是一个运行时库函数,其实现可以在:C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src\intel\ullshr.asm或者C:\Program Files (x86)\Microsoft Visual Studio …
我正在优化一种压缩算法,该算法使用跨 2 个字节的结构。但有时我希望它只解释 1 个字节,因为(我希望)映射到第二个字节的成员永远不会被写入或读取。
我是否能保证编译器不会访问第二个字节,只要 和zFmt永远wFmt不会被访问?如果不是,我可以编写一个静态断言,当这个假设错误时将停止编译吗?
struct Header {
uint8_t xFmt : 4;
uint8_t yFmt : 4;
uint8_t zFmt : 4; // must not be read/written when header is mapped to 1 byte
uint8_t wFmt : 4; // must not be read/written when header is mapped to 1 byte
};
static_assert( sizeof(Header) == 2 && alignof(Header) == 1, "alignment vital");
// --- usage ---
int main(){
// Header may be placed into memory where it …Run Code Online (Sandbox Code Playgroud) 我有一个只能以8位字节寻址的数据流,我想把它解析成6位元素并将其存储到数组中.有没有最知名的方法来做到这一点?
11110000 10101010 11001100
Run Code Online (Sandbox Code Playgroud)
成
像一个数组
111100|001010|101011|001100
Run Code Online (Sandbox Code Playgroud)
(可以零填充,只需要通过这种方式寻址)
数据是一个8位数组,也是6位的倍数,不是真的无穷无尽
根据C11,一个目标是:
#C11§3:术语,定义和符号
对象:执行环境中的数据存储区域,其内容可以表示值.
位域可以表示一个值,因此它应该是一个对象.但是,我被告知事实并非如此.
什么是正确的答案?
我想知道为什么bitfields与unions/structs一起工作,但是没有像int或那样的普通变量short.
这有效:
struct foo {
int bar : 10;
};
Run Code Online (Sandbox Code Playgroud)
但这失败了:
int bar : 10; // "Expected ';' at end of declaration"
Run Code Online (Sandbox Code Playgroud)
为什么此功能仅在联合/结构中可用而不在变量中?技术不一样吗?
编辑:
如果允许,你可以创建一个3字节的变量,而不是每次都使用struct/union成员.这就是我对结构的看法:
struct int24_t {
int x : 24 __attribute__((packed));
};
struct int24_t var; // sizeof(var) is now 3
// access the value would be easier:
var.x = 123;
Run Code Online (Sandbox Code Playgroud) 我很难理解C99标准草案(N1256)关于位域(6.7.2.1:10)的确切含义:
6.7.2.1结构和联合说明符
[...]
语义
[...]
实现可以分配任何足够大的可寻址存储单元来保存位字段.如果剩余足够的空间,则紧跟在结构中的另一个位字段之后的位字段将被打包到相同单元的相邻位中.如果剩余的空间不足,则是否将不适合的位域放入下一个单元或重叠相邻单元是实现定义的.单元内的位域分配顺序(高阶到低阶或低阶到高阶)是实现定义的.未指定可寻址存储单元的对齐.
强调的句子将我的英语技能扩展到极限:我不明白它是指单元内的各个位字段,还是单个位字段内的位排序或其他内容.
我会试着通过一个例子让我更加清楚.假设无符号整数是16位,实现选择unsigned int作为可寻址存储单元(并且字节为8位宽),并且不会出现其他对齐或填充问题:
struct Foo {
unsigned int x : 8;
unsigned int y : 8;
};
Run Code Online (Sandbox Code Playgroud)
thus, assuming x and y fields are stored inside the same unit, what is implementation-defined according to that sentence? As I understand it, it means that inside that unsigned int unit, x can be stored either at a lower address than y or vice-versa, but I'm not sure, since intuitively I'd think that if no …
bit-fields ×10
c ×7
c++ ×2
python ×2
struct ×2
bit ×1
bitarray ×1
gcc ×1
intrinsics ×1
object ×1
optimization ×1
parsing ×1
uefi ×1
unions ×1
valgrind ×1
visual-c++ ×1