二进制转换和位运算

/*
 & :按位与
 只有对应的两个二进制位均为 1 时,结果位才为 1,否则为 0
 例:
 1001 [1*2的0次方 + 0*2的1次方 + 0*2的2次方 + 1*2的3次方 = 9]
 0101 [1*2的0次方 + 0*2的1次方 + 1*2的2次方 + 0*2的3次方 = 5]
 -----
 0001 [= 1]
 
 10111011
 10101101
 ---------
 10101001
 */
printf("9 & 5 = %d\n", 9 & 5);//1
 

/* 用位与&运算符判断变量的奇偶性*/
/*
 15: 1111
 9:  1001
 
 14: 1110
 10: 1010
 奇数的最后一个都是 1,偶数的最后一位都是 0
 0:  0001
 
 1111
 0001
 -----
 0001
 
 1110
 0001
 -----
 0000
 由此可得出:a & 1 == 1//奇数
           a & 1 == 0//偶数
 */
int a = 15;
a%2 == 0 ? printf("偶数\n"):printf("奇数\n");//基数
/*
 |:按位或
 只要对应的两个二进制位有一个为 1 时,结果位就为 1,否则为 0
 例:
 1001
 0101
 -----
 1101 [=13]
 */
printf("9 | 5 = %d\n", 9 | 5);//13
/*
 ^:按位异或
 当对应的二进制位异或(不相同)时,结果为 1,否则为 0.
 1.相同数值进行异或,结果肯定是 0;
 2.交换 9^5^6 == 9^6^5
 3.任何数值跟 0 进行异或,结果还是原来的数值,9^0 == 9
 4.a^b^a == b
 例:
 1001 [9]
 1001 [9]
 -----
 0000 [=0]
 
 1001 [9]
 0101 [5]
 -----
 1100 [=12]
 
 1001 [9]
 0000 [0]
 -----
 1001 [=9]
 */
printf("9 ^ 5 = %d\n", 9 ^ 5);//12


/*
 使用位异或运算符交换两个变量的值
 */
int a = 10;
int b = 11;

/* 借助第三方变量
int temp = a;
a = b;
b = temp;
*/

/*
a = b - a;
b = b - a;
a = b + a;
*/

// a^b^a == b
a = a ^ b;//10 ^ 11
b = a ^ b;//10 ^ 11 ^ 11 = 10
a = a ^ b;//10 ^ 11 ^ 10 = 11

printf("a = %d, b = %d\n",a,b);
/*
 ~:按位取反
 对整数的各二进制数按位取反,即将0变1,1变0,符号位也取反。
 例:
 1001,写全为
 ~0000 0000 0000 0000 0000 0000 0000 1001
  1111 1111 1111 1111 1111 1111 1111 0110
 */
printf("~9 = %d\n", ~9);//-10
/*左移 <<
  1. 对于 a << n,即把整数a 的各二进制位全部左移 n 位,高位丢弃,低位补 0.左移 n 位其实就是乘以 2 的 n 次方;
  2. 由于左移是丢弃最高位,0 补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性。
//参考列
0000 0000 0000 0000 0000 0000 0000 0000
//原始列
0000 0000 0000 0000 0000 0000 0000 1001
//左移一位,末尾用 0 补齐,头部多出的 0 直接去掉
000 0000 0000 0000 0000 0000 0000 10010
//左移两位,末尾用 0 补齐
00 0000 0000 0000 0000 0000 0000 100100
 
1001 左移一位变为 10010
     左移两位变为 100100
 即:
 9<<1 -> 9 * 2的 1 次方 == 18
 9<<2 -> 9 * 2的 2 次方 == 36
 9<<n -> 9 * 2的 n 次方
 */

printf("9<<1 = %d\n",9<<1);//18
/*右移 >>
 1. 对于 a >> n,即把整数a 的各二进制位全部右移 n 位,保持符号位不变,右移 n 位其实就是除以 2 的 n 次方
 2. 为正数时,符号位为 0,最高位补 0
 3. 为负数时,符号位为 1,最高位是补 0 或补 1 取决于编译系统的规定
 
//参考列
0000 0000 0000 0000 0000 0000 0000 0000
//原始列
0000 0000 0000 0000 0000 0000 0000 1001
//第一步:保持符号位不变,符号位后面的全部右移一位,末尾多出的 1 直接去掉
0 000 0000 0000 0000 0000 0000 0000 100
//第二步:空出的一位用符号位补齐,即符号位是 0,则用 0 补齐,符号位是 1,则用 1 补齐
00000 0000 0000 0000 0000 0000 0000 100

1001 右移一位变为 100
     右移两位变为 10
 即:
 8>>1 -> 8 / 2的 1 次方 == 4
 8>>2 -> 8 / 2的 2 次方 == 2
 8>>n -> 8 / 2的 n 次方
 */
printf("8>>2 = %d\n",8>>2);//2
//输出整数在内存中的二进制形式
- (void)printBinaryWithNum:(int)number
{
    //记录现在挪到第几位 (sizeof(number*8)-1) = 31
    //number*8 字节数*8 得到总位数
    int temp = (sizeof(number)<<3) - 1;
    while (temp >= 0) {
        int value = number>>temp & 1;
        printf("%d\n",value);
        temp--;
        if ((temp+1)%4 == 0) {
            printf(" ");
        }
    }
}

 

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值