我必须说我从来没有理由使用按位运算符,但我确信我已经执行了一些可以更有效地完成它们的操作。 “转移”和“OR-ing”如何帮助您更有效地解决问题?
答案 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'
字母位置字母:
AND
chr(31)
/ binary('11111')
/(hex('1F')
=> (x & "\x1F")
('a' & "\x1F") => 1
; ('B' & "\x1F") => 2
以字母为单位获取字母位置(仅限大写字母):
AND
?
=> (x & '?')
=> XOR
或 @
(x ^ '@')
('C' & '?') => 3
; ('Z' ^ '@') => 26
以字母为单位获取字母位置(仅限小写字母):
XOR
/ chr(96)
/ binary('1100000')
=> hex('60')
(x ^ '`')
('d' ^ '`') => 4
; ('x' ^ '`') => 25
注意:使用英文字母以外的任何内容都会产生垃圾结果
答案 1 :(得分:55)
获取最大整数
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)
我用过的频率只有三种:
设置一下: a | = 1&lt;&lt;位;
清除一点: a&amp; =〜(1&lt;&lt;&lt; bit;)
测试一下是否设置了: 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)
指令代码。