6.ビット単位のいくつかの巧妙なテクニック

最小および最大ビット操作によって得られた6.1内蔵型

図1は、 // 最大int型プレゼント
 2  // get_int_max_1()整数定数オーバーフローエラーであってもよい
。3  int型get_int_max_1(){
 4      リターン1 << 31は - )1 ;
 5。 }
 6。 INT get_int_max_2(){
 7。     リターン〜 (1 << 31である);
 8。 }
 9。 // unsigned int型は、32 2桁、除去右符号ビットであり、
10  のint get_int_max_3(){
 11。     リターン((符号なし整数 - )1。 >>)1。;
12  }
 13  // タイプINTの最小値を取得し
14  INT get_int_min_1(){
 15      リターン 1 << 31である;
 16 }

 

6.2。左1と行動の権利

図1は、 // このように考えて:11110 1111は、各ビットが倍増することを意味元の基準、内のすべての+1に相当するものを左に、2進1111時間を10進数に変換しましたさらに添加することによって得られた結果
 2  // シフト一つは2を乗算に対応する左
3。 INT multiply_by_two(INT NUM){
 4。     リターン NUMを<< 1。;
 5  }
 。6  // 右分割2に対応する
図7  のint divide_by_two(INT NUM){
 8。     復帰 NUM >> 1。;
 9 }

 

2 ^ nまたは2 ^ n分割で乗算される方法6.3。

1  // mは2 ^ n倍された
2  のint multiply_by_two_power(INT M、INT N){
 3。     リターン M << N;
 4  }
 5。 // 2のm乗で割った
6。 int型 divide_by_two_power(INT M、整数nは){
 7。     リターン M << N-;
 8 }

 

6.4数が2のべき乗であるかどうかを決定します

1  // 数を分析する2の累乗ではない、
2  BOOL isFactorialofTwo(INT N-){
 3      リターン N-> 0(?N-&(N - 1))== 0falseに4  }
 。5      / * これは、2の累乗である場合、nは100 ... N-1 1111 ....でなければならない
 6         ので、演算結果が0ですか/ *

 

6.5。補完するために、元のコードからは、ビット単位の1が元のコードの反対されて、ということを理解すべきです!

1  // 逆数の数見つける
2  のint opposite_numberを(INT N-){
 3      リターン〜+ N- 1 ;
 4 }

 

6.6.统计一个二进制数中0和1的个数 1 //统计一个二进制数中1和0的个数,n&(~n+1)可以得到最后一位为1的二进制数,n|=(n+1)可以使最后一位0置为1

1 int sum_0(int n) {
2     int count = 0;
3     while (n+1)        //全部为1高位去除,结果为0
4     {
5         n |= (n + 1);
6         count++;
7     }
8     return count++;
9 }

6.7.判断一个数的奇偶性

1 //判断一个数的奇偶性
2 //高位去除,得到二进制的最后一位,0为偶数,1为奇
3 bool is_oddnumber(int n) {
4     return (n & 1) == 1;
5 }

 

6.8.不使用第三个数交换两个数

 1 /交换两个数不使用第三个数,把一般运算符的方法也用上了
 2 //一个数异或本身等于0,一个数异或0得到本身
 3 void swap(int &a,int &b) {
 4     a = a ^ b;
 5     b = a ^ b;
 6     a = a ^ b;
 7 }
 8 void swap_1(int &a, int &b) {
 9     a = a - b;
10     b = a + b;
11     a = b - a;
12 }

 

6.9.不使用+,-,*,/完成整数相加

 1 int Add(int num1, int num2)
 2 {
 3     int sum, carry;
 4     do {
 5         //将两个数异或,得到不进位的结果
 6         sum = num1 ^ num2;
 7         //将两个位运算,得到进位的结果
 8         carry = (num1 & num2) << 1;
 9         //很显然,我们只要把进位的结果+上不进位的结果就可以得到我们想要的,
10         //但是,我们不能使用+运算符,我们知道,进位的结果是1不断的左移,当进位的结果和不进位的结果不断异或,最左边的1
11         //超过了不进位的结果最左边的1,那么最后一次与运算显然结果为0,于是,最后一次异或运算就是我们想要的相加的结果
12         num1 = sum;
13         num2 = carry;
14     } while (num2 != 0); //将结果相加的过程就重复上述过程,直到进位为0
15 
16     return sum;
17 }

 

おすすめ

転載: www.cnblogs.com/Royzzzzz/p/10975347.html