开发人员应该了解哪些有用的按位操作符代码?

时间:2009-10-07 17:44:35

标签: language-agnostic bit-manipulation bit

我必须说我从来没有理由使用按位运算符,但我确信我已经执行了一些可以更有效地完成它们的操作。 “转移”和“OR-ing”如何帮助您更有效地解决问题?

11 个答案:

答案 0 :(得分:132)

对字符串(字符)使用按位运算

将字母转换为小写

  • OR by space => (x | ' ')
  • 即使字母已小写
  • ,结果也始终为小写
  • 例如。 ('a' | ' ') => 'a'; ('A' | ' ') => 'a'

将信件转换为大写

  • AND by underline => (x & '_')
  • 即使字母已经大写
  • ,结果也始终为大写
  • 例如。 ('a' & '_') => 'A'; ('A' & '_') => 'A'

反转信件的案例:

  • XOR by space => (x ^ ' ')
  • 例如。 ('a' ^ ' ') => 'A'; ('A' ^ ' ') => 'a'

字母位置字母:

    {li> AND chr(31) / binary('11111') /(hex('1F') => (x & "\x1F")
  • 结果在1..26范围内,字母大小写不重要
  • 例如。 ('a' & "\x1F") => 1; ('B' & "\x1F") => 2

以字母为单位获取字母位置(仅限大写字母):

    {li> AND ? => (x & '?') => XOR @ (x ^ '@')
  • 例如。 ('C' & '?') => 3; ('Z' ^ '@') => 26

以字母为单位获取字母位置(仅限小写字母):

    通过反引号/ XOR / chr(96) / binary('1100000') =>
  • hex('60') (x ^ '`')
  • 例如。 ('d' ^ '`') => 4; ('x' ^ '`') => 25

注意:使用英文字母以外的任何内容都会产生垃圾结果

答案 1 :(得分:55)


  • 对整数的按位运算(int)

获取最大整数

int maxInt = ~(1 << 31);
int maxInt = (1 << 31) - 1;
int maxInt = (1 << -1) - 1;

获取最小整数

int minInt = 1 << 31;
int minInt = 1 << -1;

获取最长时间

long maxLong = ((long)1 << 127) - 1;

乘以2

n << 1; // n*2

除以2

n >> 1; // n/2

乘以2的第m次幂

n << m;

除以2的第m次幂

n >> m;

检查奇数

(n & 1) == 1;

兑换两个值

a ^= b;
b ^= a;
a ^= b;

获取绝对值

(n ^ (n >> 31)) - (n >> 31);

获取最多两个值

b & ((a-b) >> 31) | a & (~(a-b) >> 31);

获取两个值的最小值

a & ((a-b) >> 31) | b & (~(a-b) >> 31);

检查两者是否具有相同的符号

(x ^ y) >= 0;

计算2 ^ n

2 << (n-1);

是否为2的阶乘

n > 0 ? (n & (n - 1)) == 0 : false;

模2 ^ n对m

m & (n - 1);

获取平均值

(x + y) >> 1;
((x ^ y) >> 1) + (x & y);

获取n的第m位(从低到高)

(n >> (m-1)) & 1;

将n的第m位设置为0(从低到高)

n & ~(1 << (m-1));

n + 1

-~n

n - 1

~-n

获取对比号

~n + 1;
(n ^ -1) + 1; 

if(x == a)x = b; if(x == b)x = a;

x = a ^ b ^ x;

答案 2 :(得分:40)

参见着名的Bit Twiddling Hacks
大多数乘法/除法都是不必要的 - 编译器会自动执行此操作,您只会混淆人。

但是,如果你使用硬件或通信协议,有一堆'检查/设置/切换位N'类型的黑客非常有用。

答案 3 :(得分:12)

我用过的频率只有三种:

  1. 设置一下: a | = 1&lt;&lt;位;

  2. 清除一点: a&amp; =〜(1&lt;&lt;&lt; bit;)

  3. 测试一下是否设置了: a&amp; (1&lt;&lt;&lt; bit ;;

答案 4 :(得分:6)

Matters Computational: Ideas, Algorithms, Source Code, by Jorg Arndt (PDF)。这本书包含大量内容,我通过http://www.hackersdelight.org/

的链接找到了它
  

平均无溢出

     

计算两个平均值(x + y)/ 2的例程   参数x和y是

static inline ulong average(ulong x, ulong y)
// Return floor( (x+y)/2 )
// Use: x+y == ((x&y)<<1) + (x^y)
// that is: sum == carries + sum_without_carries
{
    return (x & y) + ((x ^ y) >> 1);
}

答案 5 :(得分:2)

您可以压缩数据,例如整数集合:

答案 6 :(得分:2)

我使用按位运算符有效地实现bitstrings的距离计算。在我的应用程序中,位串用于表示离散空间中的位置(octree,如果您感兴趣,则使用Morton ordering编码)。需要进行距离计算以了解网格上的点是否落在特定半径内。

答案 7 :(得分:2)

计算设置位,找到最低/最高设置位,找到nth-from-top / bottom设置位和其他位可能很有用,值得查看bit-twiddling hacks站点。

那就是说,这种事情不是日常重要的。有一个库是有用的,但即使这样,最常见的用途是间接的(例如使用bitset容器)。另外,理想情况下,这些是标准的库函数 - 在某些平台上使用专门的CPU指令可以更好地处理它们。

答案 8 :(得分:1)

1)除以2的幂

foo >>= x;(除以2的幂)

foo <<= x;(乘以2的幂)

2)交换

x ^= y;
y = x ^ y;
x ^= y;

答案 9 :(得分:1)

虽然通过移位进行乘法/除法看起来很漂亮,但我偶尔需要的是将布尔值压缩成位。为此,您需要按位AND / OR,并且可能需要位移/反转。

答案 10 :(得分:1)

我想要一个函数来将数字舍入到下一个最高的2的幂,所以我访问了Bit Twiddling网站,该网站已被多次提出并提出了这个:

i--;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i++;

我在size_t类型上使用它。它可能不会在签名类型上发挥出色。如果您担心具有不同大小类型的平台的可移植性,请在适当的位置使用#if SIZE_MAX >= (number)指令代码。