Tag: 位操作

在C中使用位字段时的字段顺序

我有一个以下类型的结构 typedef struct { unsigned int a : 8; unsigned int b : 6; unsigned int c : 2; }x, *ptr; 我想做的是改变字段c的值。 我做了类似以下的事情 x structure = { 0 }; x->c = 1; 当我查看内存映射时,我希望找到00 01 ,但我找到00 40 。 看起来在排列第二个字节时,它将c字段放在最低位中,将b字段放在最高位中。 我在GCC和Windows编译器上都看到了这一点。 现在,我做的是以下,这是正常的。 unsigned char ptr2 = (unsigned char*) ptr *(ptr2 + 1) &= 0xFC *(ptr2 + 1) […]

将32 0/1值打包到单个32位变量的位中的最快方法是什么?

我正在使用x86或x86_64机器。 我有一个数组unsigned int a[32]所有元素的值都是0或1.我想设置单个变量unsigned int b这样(b >> i) & 1 == a[i]将保持为a的所有32个元素。 我正在使用Linux上的GCC(我猜不应该这么做)。 在C中执行此操作的最快方法是什么?

什么是零宽度位域

可能重复: 零长度位域的实际应用 为什么有些结构具有零宽度位域,为什么需要它? struct foo { int a:3; int b:2; int :0; // Force alignment to next boundary. int c:4; int d:3; }; int main() { int i = 0xFFFF; struct foo *f = (struct foo *)&i; printf(“a=%d\nb=%d\nc=%d\nd=%d\n”, f->a, f->b, f->c, f->d); return 0; } 上述程序的输出是 manav@os-team:~/programs/test$ ./a.out a=-1 b=-1 c=-8 d=0 请解释为什么这些值是负数,以及结构内部这些变量的内存布局?

确定字节中的哪个位被设置

我有一个用于bitflags的byte 。 我知道在任何给定时间都设置了byte中的一个且只有一个位。 例如: unsigned char b = 0x20; //(00100000) 6th most bit set unsigned char b = 0x20; //(00100000) 6th most bit set 我目前使用以下循环来确定设置了哪个位: int getSetBitLocation(unsigned char b) { int i=0; while( !((b >> i++) & 0x01) ) { ; } return i; } 如何最有效地确定设定位的位置? 我可以不经迭代地完成这项工作吗?

C问题:off_t(和其他有符号整数类型)的最小值和最大值

我偶尔会遇到一个整数类型(例如POSIX有符号整数类型off_t ),其中有一个宏的最小值和最大值是有帮助的,但我不知道如何制作一个真正可移植的宏。 对于无符号整数类型,我一直认为这很简单。 0表示最小值, ~0表示最大值。 我已经阅读了几个不同的SO线程,建议使用-1而不是-1来实现可移植性。 这里有一个有争议的有趣线程: c ++ – 使用-1将所有位设置为true是否安全? – 堆栈溢出 然而,即使在阅读了这个问题后,我仍然感到困惑。 另外,我正在寻找兼容C89和C99的东西,所以我不知道是否适用相同的方法。 说我有一种uint_whatever_t 。 难道我不能先转为0然后按位补码? 这样可以吗? #define UINT_WHATEVER_T_MAX ( ~ (uint_whatever_t) 0 ) 有符号的整数类型看起来像是一个更难以破解的坚果。 我已经看到了几种不同的可能解决方案,但只有一种似乎是可移植的。 无论是那个还是不正确的。 我在谷歌搜索OFF_T_MAX和OFF_T_MIN时找到了它。 感谢Christian Biere: #define MAX_INT_VAL_STEP(t) \ ((t) 1 << (CHAR_BIT * sizeof(t) – 1 – ((t) -1 < 1))) #define MAX_INT_VAL(t) \ ((MAX_INT_VAL_STEP(t) – 1) + […]

使用C中的按位运算符检查数字是否为非零

使用合法运算符检查数字x是否非零! 。 示例: isNonZero(3) = 1 , isNonZero(0) = 0 法律操作: ~ & ^ | + << >> 注意:只应使用按位运算符。 if , else , for等不能使用。 编辑1:运营商数量不应超过10。 Edit2:将int大小视为4个字节。 int isNonZero(int x) { return ???; } 用! 这将是微不足道的,但我们如何不使用! ?

意外的C / C ++按位移位运算符结果

我想我会疯了。 我有一段代码需要创建一个(无符号)整数,其中N后续位设置为1.确切地说,我有一个位掩码,在某些情况下,我想将它设置为一个实心的rnage。 我有以下function: void MaskAddRange(UINT& mask, UINT first, UINT count) { mask |= ((1 << count) – 1) << first; } 简单来说: 1 << count二进制表示中的1 << count是100…000 (零的count是count ),从这样的数字中减去1得到011…111 ,然后我们first它左移。 当满足以下明显限制时,上述结果应产生正确的结果: first + count <= sizeof(UINT)*8 = 32 请注意 ,它也应该适用于“极端”情况。 如果count = 0我们有(1 << count) = 1 ,因此((1 << count) – 1) = 0 。 […]

Bitshift和整数推广?

通常,C要求将二元运算符的操作数提升为更高级别操作数的类型。 这可以被利用来避免用详细的强制转换来填充代码,例如: if (x-48U<10) … y = x+0ULL << 40; 等等 但是,我发现,至少对于gcc,这种行为不适用于位移。 即 int x = 1; unsigned long long y = x << 32ULL; 我希望右手操作数的类型能够将左手操作数提升为unsigned long long以便移位成功。 但相反,gcc会打印一个警告: warning: left shift count >= width of type gcc是否被破坏,或者标准是否对比特提升的类型提升规则有所例外?

十进制到二进制

我有一个数字,我想在C中转换为二进制(从十进制)。 我希望我的二进制文件总是以5位(小数字永远不会超过31)。 我已经有一个通过分割手动完成的function,但很难将其填充到5位。 有没有更简单的方法? 也许使用按位移位? 我也希望二进制文件在char *表示

移位32位变量32位有什么不好?

我最近选择了Bruce Schneier的Applied Cryptography副本,这是一本很好的阅读。 我现在明白本书中概述的几种算法是如何工作的,我想在C中开始实现其中的一些算法。 许多算法的共同点是将x位密钥分成几个较小的y位密钥。 例如,Blowfish的密钥X是64位,但是你需要将它分成两个32位的一半; Xl和Xr。 这就是我陷入困境的地方。 我对C相当不错,但对于按位运算符等,我并不是最强的。 在IRC上获得一些帮助之后,我设法提出了这两个宏: #define splitup(a, b, c) {b = a >> 32; c = a & 0xffffffff; } #define combine(a, b, c) {a = (c << 32) | a;} 其中a是64位,b和c是32位。 但是,编译器警告我,我正在将32位变量移位32位。 我的问题是这些: 移位32位变量32位有什么不好? 我猜它是未定义的,但这些宏似乎确实有效。 另外,你会建议我换一种方式吗? 正如我所说的,我对C非常熟悉,但是按位运算符等仍让我头疼。 编辑 我发现我的组合宏实际上并没有组合两个32位变量,而只是简单地将0和0相加,并得到一个结果。 所以,除了我以前的问题,我仍然没有一种方法将两个32位变量组合起来得到一个64位变量; 关于如何做的建议将不胜感激。