位运算的一些注意事项

1. 左移“<<”和右移“>>”

两边的操作数都不能为负数,如-1 << 1, 1 << -1 会报错;

右操作数位数不能超过左操作数的位数大小,如1 << 33,会报错;

左移或右移一位,相当于乘以或除以2,当然只适用于正数,注意不要越界;


2. 注意“&”和“&&”,“|”和“||”的区别

(2&5)为0,即false

(2&&5)为true


3. “&”操作

可以被用于很快地知道一个数的奇偶性

(x & 1)? printf("Odd"): printf("Even");

4. “~”操作

对一个特别小的数取反,如果结果是无符号数,则会变成一个很大的数;如果结果是有符号数,则可能会变成一个负数

#include <stdio.h>
#include <stdlib.h>

int main()
{
    unsigned int x = 1;
    printf("Signed Result %d \n", ~x);
    printf("Unsigned Result %ud \n", ~x);
    return 0;
}
/*
 * Output: 
 * Signed Result -2 
 * Unsigned Result 4294967294d 
 */


5.异或“^” 的常用场景

1)一个数组中,除了一个元素之外,其他元素都是出现两次,找出出现次数为1的元素

#include <stdio.h>
#include <stdlib.h>

int findOdd(int arr[], int n) {
    int res = 0, i;
    for (i = 0; i < n; i++)
        res ^= arr[i];
    return res;
}

int main()
{
    int arr[] = {12, 12, 14, 90, 14, 14, 14};
    int n = sizeof(arr)/sizeof(arr[0]);
    printf ("The odd occurring element is %d ", findOdd(arr, n));
    return 0;
}
/*
 * Output:
 * The odd occurring element is 90
 */

2) 一个数组中,除了两个元素之外,其他元素都是出现两次,找出出现次数为1的两个元素

#include <stdio.h>
#include <stdlib.h>

//将数组分为两个子数组,每个数组中含有一个带求解结果
void get2NonRepeatingNos(int arr[], int n, int *x, int *y)
{
    int xor = arr[0];
    int diff;
    int i;
    *x = 0;
    *y = 0;

    /* Get the xor of all elements */
    for(i = 1; i < n; i++)
        xor ^= arr[i];

    /* 因为结果是两个不同的值,必然对应的二进数位存在不同的值
     */
    diff = xor & ~(xor-1);

      for(i = 0; i < n; i++)
      {
          if(arr[i] & diff)
              *x = *x ^ arr[i]; /*XOR of first set */
          else
              *y = *y ^ arr[i]; /*XOR of second set*/
      }
}

/* Driver program to test above function */
int main()
{
      int arr[] = {2, 3, 7, 9, 11, 2, 3, 11};
      int *x = (int *)malloc(sizeof(int));
      int *y = (int *)malloc(sizeof(int));
      get2NonRepeatingNos(arr, 8, x, y);
      printf("The non-repeating elements are %d and %d", *x, *y);
      getchar();
}
/*
 * Output:
 * The non-repeating elements are 7 and 9
 */


3)不使用临时变量,交换两个数

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x = 21, y = 38;
    x = x ^ y;  // x now becomes 51
    y = x ^ y;  // y becomes 21
    x = x ^ y;  // x becomes 38

    printf("After Swapping: x = %d, y = %d", x, y);
    return 0;
}
/*
 * Output:
 * After Swapping: x = 38, y = 21
 */

4)不使用“+”、“-”、“*”、“/”,计算两个数的和

见解法:http://blog.csdn.net/fjx1173865548/article/details/77852832




参考:http://www.geeksforgeeks.org/interesting-facts-bitwise-operators-c/


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值