什么有用的位操作者代码的技巧,应当开发一个知道的吗?[关闭]
-
20-09-2019 - |
题
我必须说,我从来没有引起使用按位经营者,但我相信有一些行动,我们执行那会是更有效地完成它们。怎么会有"转移"和"或ing"帮你解决问题更有效?
解决方案
请参阅著名位操作黑客结果 大部分的乘法/除法的人是不必要的 - 编译器会自动做到这一点,你只会混淆人们
。但也有一堆,“检查/设置/翻转比特N”型黑客如果用硬件或通信协议工作是非常有用的。
其他提示
对字符串(字符)使用按位运算
将字母转换为 小写:
OR
按空格 =>(x | ' ')
- 即使字母已经是小写,结果也始终是小写
- 例如。
('a' | ' ') => 'a'
;('A' | ' ') => 'a'
将字母转换为 大写:
AND
通过下划线=>(x & '_')
- 即使字母已经是大写,结果也始终是大写
- 例如。
('a' & '_') => 'A'
;('A' & '_') => 'A'
倒置 信函的案例:
XOR
按空格=>(x ^ ' ')
- 例如。
('a' ^ ' ') => 'A'
;('A' ^ ' ') => 'a'
信的 位置 用字母表表示:
AND
经过chr(31)
/binary('11111')
/(hex('1F')
=>(x & "\x1F")
- 结果在 1..26 范围内,字母大小写并不重要
- 例如。
('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
笔记:使用英文字母以外的任何内容都会产生垃圾结果
- 整数的按位运算(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;
对 m 取模 2^n
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;
如果 (x==a) x=b;如果 (x==b) x=a;
x = a ^ b ^ x;
我曾经经常使用过的只有三个:
稍微设置一下:a |= 1 << 位;
清除一点:a &= ~(1 << 位);
测试是否已设置位:a & (1 << 位);
事项计算:思想,算法,源代码,通过了Jorg阿恩特(PDF) 。这本书包含吨的东西,我发现它通过一个链接 http://www.hackersdelight.org/
平均无溢出
一个用于平均的计算(X + Y)的2/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); }
您可以压缩数据,例如整数的集合:
- 查看集合中哪些整数值出现的频率更高
- 使用短位序列来表示出现频率较高的值 (以及更长的位序列来表示出现频率较低的值)
- 连接位序列:例如,结果位流中的前 3 位可能代表一个整数,然后接下来的 9 位代表另一个整数,等等。
1)分割/乘以2的幂
foo >>= x;
(由2的幂除)
foo <<= x;
(由2的幂乘)
2)交换
x ^= y;
y = x ^ y;
x ^= y;
计算设定位,找到最低/最高位置,找到n-从顶/底设置的位和其他可能是有用的,这是值得看的 位摆弄黑客 网站。
这就是说,这种事情不是日常重要的。有一个图书馆,但即使是最普通的用途是间接的(例如使用特集容器)。此外,理想的是,这将是标准图书馆功能-他们很多都是更好地处理使用专门CPU说明,在某些平台上。
虽然乘以/由变速分割似乎漂亮,我在同时需要一次的唯一事情是压缩布尔成比特。为此你需要按位AND / OR,大概比特移位/反转。
我想一个函数四舍五入号码2的下一个最高权力,所以我参观了位操作的网站,一直带到了好几次,并用此想出了:
i--;
i |= i >> 1;
i |= i >> 2;
i |= i >> 4;
i |= i >> 8;
i |= i >> 16;
i++;
我使用它在一个size_t
类型。它可能不会签署类型打好。如果你担心的便携性与不同尺寸类型的平台上,撒上你的代码在适当的地方#if SIZE_MAX >= (number)
指令。