在 C 中,如何以通用方式设置任意大小的 int 的前八位

In C, how to set first eight bits of any sized int in a generic way

如何将任何整数类型的前八位(最低有效位)设置为全零?基本上用 0x00.

对任何整数类型进行按位与运算

我需要的是适用于任何整数大小的通用解决方案,但不必创建掩码将所有高位设置为 1

换句话说:

0xffff             & 0x00 = 0xff00
0xaabbccddeeffffff & 0x00 = 0xaabbccddeeffff00

有移位:

any_unsigned_integer = any_unsigned_integer >> 8 << 8;

C 非运算符 ~ 将反转给定值的所有位,以便获得仅清除低八位的掩码:

int val = 123456789;
int other_val = val & ~0xff; // AND with binary 1111 ... 1111 0000 0000
val &= ~0xff;                // alternative to change original variable.

如果您有更宽(或更细)的类型,0xff 应该是正确的类型,例如:

long val = 123456789L;
long other_val = val & ~(long)0xff;
val &= ~(long)0xff;          // alternative to change original variable.

不为高位创建掩码的一种方法是使用 &^ 运算符的组合:x = x ^ (x & 0xFF);(或者,使用复合赋值: x ^= x & 0xFF;).

通用解决方案无掩码,任意位数

#define RESETB(val, nbits) ((val) ^ ((val) & ((1ULL << (nbits)) - 1)))

甚至更好

#define RESETB(val, nbits) ((val) ^ ((val) & ((nbits) ? ((nbits) >= sizeof(val) * CHAR_BIT ? ((1ULL << (sizeof(val) * CHAR_BIT)) - 1) : ((1ULL << (nbits)) - 1)) : 0)))

最简单的解决方案适用于对负数使用 2 的补码表示的体系结构上的所有整数类型:

val = val & ~0xff;

原因是 ~0xff 的计算结果为 -256,类型为 int。让我们考虑 val:

所有可能的类型
  • 如果val的类型小于intval被提升为int,掩码操作按预期工作,结果转换回val.
  • 的类型
  • 如果 val 的类型是有符号的,-256 将转换为 val 的类型并保留其值,因此复制符号位,并正确执行掩码。
  • 如果 val 的类型是无符号的,将 -256 转换为这种类型会产生值 TYPE_MAX + 1 - 256,除了 8 个低位外,所有位都已设置,同样是正确的掩码操作。

另一个适用于所有负值表示的简单解决方案是:

val = val ^ (val & 0xff);

它需要将值存储到变量中以避免多重计算,而第一个建议可以应用于任何具有潜在副作用的表达式:

return my_function(a, b, c) & ~0xff;