在 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
的类型小于int
,val
被提升为int
,掩码操作按预期工作,结果转换回val
. 的类型
- 如果
val
的类型是有符号的,-256
将转换为 val
的类型并保留其值,因此复制符号位,并正确执行掩码。
- 如果
val
的类型是无符号的,将 -256
转换为这种类型会产生值 TYPE_MAX + 1 - 256
,除了 8 个低位外,所有位都已设置,同样是正确的掩码操作。
另一个适用于所有负值表示的简单解决方案是:
val = val ^ (val & 0xff);
它需要将值存储到变量中以避免多重计算,而第一个建议可以应用于任何具有潜在副作用的表达式:
return my_function(a, b, c) & ~0xff;
如何将任何整数类型的前八位(最低有效位)设置为全零?基本上用 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
的类型小于int
,val
被提升为int
,掩码操作按预期工作,结果转换回val
. 的类型
- 如果
val
的类型是有符号的,-256
将转换为val
的类型并保留其值,因此复制符号位,并正确执行掩码。 - 如果
val
的类型是无符号的,将-256
转换为这种类型会产生值TYPE_MAX + 1 - 256
,除了 8 个低位外,所有位都已设置,同样是正确的掩码操作。
另一个适用于所有负值表示的简单解决方案是:
val = val ^ (val & 0xff);
它需要将值存储到变量中以避免多重计算,而第一个建议可以应用于任何具有潜在副作用的表达式:
return my_function(a, b, c) & ~0xff;