目录
1.negate(取负)
要求:将所给数x取负。
操作:将操作数取反+1。
/*
* negate - return -x
* Example: negate(1) = -1.
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 5
* Rating: 2
*/
int negate(int x) {
return ~x+1;
}
2.bitOr(两数相或)
要求:只利用 ~ 和 & 操作,将数 x 和 y 相或。
操作:
取或,等价于将两个数的取反值~x, ~y相与后,再取反。
/*
* bitOr - x|y using only ~ and &
* Example: bitOr(6, 5) = 7
* Legal ops: ~ &
* Max ops: 8
* Rating: 1
*/
int bitOr(int x, int y) {
return ~(~x&~y);
}
3.conditional(选择运算符)
要求:用逻辑运算实现三目运算:x ? y : z。
思路:
构造一个数 f,方便选择输出。
f = ~(!x) + 1; 当x为0时,f 的每一位全为1;当x不为0时,f 的每一位全为0。
- 取1的反(
11111..110) +1 后,所有位都为1; - 取0的反(
11111..111) +1 后,所有位都为0(溢出)。
之后选择输出y或z:return (z & f) + (y & ~f);
int conditional(int x, int y, int z) {
int f = ~(!x)+1; //x为0,f每位全为1;x不为0,f每位全为0。
return (y & ~f) + (z & f);
}
4.byteNot(对某个字节取反)
要求:将所给数 x 的第 n 个字节取反。
思路:
取反可以用数位为1的数进行异或(^)操作,因为:
- 原来数位为1,和1取异或后变为0;
- 原来数位为0,和1取异或后变为1。
所以可以构造只有当前字节所在数位为1,其他位为0的数,和所给数相异或。
一个字节占 8 个数位。
第 n 个字节,需要将数 0xff (11111111 = 255) 左移 8*n 个数位。
但是不能用乘法,所以可以将 8 表示为 2^3,构造数 y 为:y = n << 3。
之后和 x 相异或,就把第n个字节取反了。
/*
* byteNot - bit-inversion to byte n from word x
* Bytes numbered from 0 (LSB) to 3 (MSB)
* Examples: getByteNot(0x12345678,1) = 0x1234A978
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 2
*/
int byteNot(int x, int n) {
int t = 0xff; //255:11111111
t <<= n<<3; //左移n*8位,变为00000..0011111111000..00
return x ^ t;
}
经验: 取反操作,异或上1。
5.allEvenBits
要求:判断数x的偶数数位是否都为1。
思路:
方法1:
int类型的数,偶数都为1,便是:01010101…0101。
所以先将数x的奇数数位全部变为0,然后判断其是否和上面的数相等就行了。
如何将数x的奇数数位全部变为0,偶数数位不变?
构造奇数数位全为0,偶数数位全为1的数y,和数x相与。
如何判断数x是否为 01010101…0101?
构造出该数,和数x相异或,看结果是否为0。若为0,则完全一致。
如何构造出奇数数位全为0,偶数数位全为1的数(01010101…0101)?
先构造出8位,再进行左移操作后相或。
int y=0x55; y |= y<<8; y |= y<<16;
方法2:
构造奇数数位全为1,偶数数位全为0的数(10101010…1010),判断其和数 x 相或后是否所有数位全为1。如果是,则说明数 x 的偶数数位全为1。
如何判断是否一个数位全为1呢?
取反看其是否为0。或者直接判断其是否为11111(取^操作)
/*
* allEvenBits - return 1 if all even-numbered bits in word set to 1
* Examples allEvenBits(0xFFFFFFFE) = 0, allEvenBits(0x55555555) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
int allEvenBits(int x) {
//方法1:
int y=0x55;
y |= y<<8;
y |= y<<16; //构造32位偶数位置全为1,奇数位置全为0的数:0101 0101...
x &= y; //先将x的奇数位上的值全部变为0
return !(x^y); //如果x
位操作与逻辑运算在C语言中的应用

本文详细介绍了C语言中位操作符的使用,包括取负、按位或、条件运算、字节取反、判断偶数位、字节交换、位掩码、大小比较、适合短整型、适合位数、判断最小值、溢出检查、循环左移、次幂检测以及原码到补码转换。通过实例解析了各种位操作的实现思路和步骤,展示了位运算在解决计算问题中的灵活性。
最低0.47元/天 解锁文章
973





