二进制与位运算

二进制与位运算

补码

计算机中,为了方便计算,整数一般在计算机中都以补码的形式存储

  • 补码的计算公式:
    • 正数:原码,反码,补码都相同
    • 负数:补码 = 反码 + 1
      • 负数在计算补码的过程中,符号位保持不变,其他位取反+1
  • 补码与原码的转换
    • 正数:补码、反码、原码都相同
    • 负数:
      • 补码->原码 :取反 +1
      • 原码->补码: 取反 + 1

Java中的位运算

位运算概述

  • &:按位与
  • |:按位或
  • ~:按位非
  • ^:按位异或
  • >>:右移
  • <<:左移
  • >>>:无符号右移

位运算详解

为了演示方便,以下位运算均以8位的byte进行操作,且计算机中位运算都是以补码的形式参与位运算

按位与

同为1则位1,否则为0

  • 8 & 11:00001000 & 00001011 = 00001000 结果为8
  • -8 & 11:11111000(补码) & 00001011 = 00001000 结果为8

按位或

全0为0,否则为1

  • 8 | 11:00001000 | 00001011 = 00001011 结果为 11
  • -8 | 11:11111000(补码) | 00001011 = 11111011(补码) 求得原码: 10000101 结果为-5

按位非

直接取反,遇1则0,遇0则1

  • ~8:00001000 按位非-> 11110111(得到补码) 计算原码->10001001 结果为 -9
  • ~-8:11111000 按位非->00000111 ->正数补码就是原码,结果为7

按位异或

相同为0,不同为1

  • 8 ^ 11:00001000 按位异或 00001011 = 00000011 结果为3
    • 再次与11进行异或: 00000011 ^ 00001011 = 00001000 结果有变回8
    • 结论:异或一个相同的数字偶数次,结果仍为这个数字

左移

<< : 左移运算符,将操作书的二进制整体左移,右边补0
- 正数的左移n位,结果为 正数 * 2的(n%数据类型的长度)次方,

右移

>>:将操作书的二进制整体右移指定位数,空出的位以符号位为准填充
- 正数的右移n位,结果为 正数/2的(n%数据类型长度)次方
- 负数右移最终结果为-1,因为'111111111111111111111'就是-1的补码形式

无符号右移

低位舍弃,高位补0

位运算的优先级

  • ~
  • << >> >>>
  • &
  • ^
  • |

常见的位运算应用

对于任意整数a和b,以下表达式结果均成立

  • a | 0 == a
  • a & 0 == 0
  • a & -1 == a (-1的补码是一串1)
  • a^a == 0
  • a ^ 0 == a
  • a |(a &b) ==a
  • a &(a | b) == a

常见应用

  1. 判断奇偶数
    a & 1 == 0:a为偶数
    a & 1 == 1:a为奇数
    原理:偶数的二进制的最后一位为0,而奇数的最后一位为1,而参与位运算的1除了最后一位为1,其余全为0,结果也是不言而喻,偶数的结果就是0,奇数最后一位1&1,结果就为1
  2. 交换变量
    一个整数异或一个相同的数数次,其结果仍为这个数字.
    int a = 2;
    int b = 3;
    a ^= b;
    b ^= a;//b = b^a 拆开来就是 b = b ^(a ^b)  此时b就=a了
    a ^= b;//a = a^b 拆开来就是 a = (a ^b) ^ b 此时a就=b了
  1. 变换符号
    System.out.println(-2 == (~2 +1)); 结果为true,~a + 1 等价于 -a
  2. 求绝对值
    int i = a>>(a的长度-1);//此处长度指的是基本数据类型short,byte,int,long的长度,如果a是整数则得到的结果为0,负数则为-1
    System.out.println( i == 0?a:(~a + 1));

5.取余运算
a%b == a&(b-1) 注意:只有b为2的n次方的时候可以使用此方法

posted @ 2021-03-31 17:04  Venking-  阅读(453)  评论(0)    收藏  举报