关于位运算的应用

位运算的应用

提供一些关于位运算的函数应用,有C语言和Python语言两个版本

取绝对值

在一些机器上,位运算的效率要比n > 0 ? n : -n

左移右移

C++代码

int Abs(int n) {
  return (n ^ (n >> 31)) - (n >> 31);
  /* n>>31 取得 n 的符号,若 n 为正数,n>>31 等于 0,若 n 为负数,n>>31 等于 -1
    若 n 为正数 n^0=n, 数不变,若 n 为负数有 n^(-1)
    需要计算 n 和 -1 的补码,然后进行异或运算,
    结果 n 变号并且为 n 的绝对值减 1,再减去 -1 就是绝对值 */
}

Python代码

def Abs(n):
    return (n ^ (n >> 31)) - (n >> 31)
    """
    n>>31 取得 n 的符号,若 n 为正数,n>>31 等于 0,若 n 为负数,n>>31 等于 -1
    若 n 为正数 n^0=n, 数不变,若 n 为负数有 n^(-1)
    需要计算 n 和 -1 的补码,然后进行异或运算,
    结果 n 变号并且为 n 的绝对值减 1,再减去 -1 就是绝对值
    """

异或

int v;           // we want to find the absolute value of v
unsigned int r;  // the result goes here 
int const mask = v >> sizeof(int) * CHAR_BIT - 1;

r = (v + mask) ^ mask;

比较两个数的最大最小值

一般情况下效率比 a > b ? a : b 高。

C++

// 如果 a >= b, (a - b) >> 31 为 0,否则为 -1
int max(int a, int b) { return (b & ((a - b) >> 31)) | (a & (~(a - b) >> 31)); }
int min(int a, int b) { return (a & ((a - b) >> 31)) | (b & (~(a - b) >> 31)); }

Python

# 如果 a >= b, (a - b) >> 31 为 0,否则为 -1
def max(a, b):
    return b & ((a - b) >> 31) | a & (~(a - b) >> 31)
def min(a, b):
    return a & ((a - b) >> 31) | b & (~(a - b) >> 31)

其他版本

int x;  // we want to find the minimum of x and y
int y;   
int r;  // the result goes here 

r = y ^ ((x ^ y) & -(x < y)); // min(x, y)
r = x ^ ((x ^ y) & -(x < y)); // max(x, y)
Quick and dirty versions

如果知道INT_MIN <= x - y <= INT_MAX,那么您可以使用下面的方法,它更快,因为(x - y)只需要计算一次。请注意,1989年的ANSIC规范没有指定带符号右移的结果,因此这些是不可移植的。如果在溢出时抛出异常,则x和y的值应该是无符号的,或者在减法时转换为无符号的,以避免不必要地抛出异常,但是右移需要一个有符号的操作数来产生所有的1位,所以在那里转换为有符号的。


r = y + ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // min(x, y)
r = x - ((x - y) & ((x - y) >> (sizeof(int) * CHAR_BIT - 1))); // max(x, y)

交换两个数

这种方式只能用来交换两个整数,使用范围有限。
对于一般情况下的交换操作,推荐直接调用 algorithm 库中的 std::swap 函数。

void swap(int &a, int &b) { a ^= b ^= a ^= b; }

操作一个数的二进制位

获取一个数二进制的某一位:

C++

// 获取 a 的第 b 位,最低位编号为 0
int getBit(int a, int b) { return (a >> b) & 1; }

Python

# 获取 a 的第 b 位,最低位编号为 0
def getBit(a, b):
    return (a >> b) & 1

将一个数二进制的某一位设置为 0 0 0

C++

// 将 a 的第 b 位设置为 0 ,最低位编号为 0
int unsetBit(int a, int b) { return a & ~(1 << b); }

Pyhton

# 将 a 的第 b 位设置为 0 ,最低位编号为 0
def unsetBit(a, b):
    return a & ~(1 << b)

将一个数二进制的某一位设置为 1 1 1

C++

// 将 a 的第 b 位设置为 1 ,最低位编号为 0
int setBit(int a, int b) { return a | (1 << b); }

Pyhton

# 将 a 的第 b 位设置为 1 ,最低位编号为 0
def setBit(a, b):
    return a | (1 << b)

将一个数二进制的某一位取反:

C++

// 将 a 的第 b 位取反 ,最低位编号为 0
int flapBit(int a, int b) { return a ^ (1 << b); }

Pyhton

# 将 a 的第 b 位取反 ,最低位编号为 0
def flapBit(a, b):
    return a ^ (1 << b)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值