位运算基础

Posted 5ycode

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算基础相关的知识,希望对你有一定的参考价值。

机器数

一个数在计算机中的二进制表示形式,就是这个数的机器数。

  • 二进制显示

  • 高位存放符号,正数是0,负数是1

位运算法符

与运算符 &

两个位都为1则为1,否则为0

printFormat(101);
printFormat(-101);
printFormat(101&101);
结果:
0000 0000 0000 0000 0000 0000 0110 0101 
1111 1111 1111 1111 1111 1111 1001 1011 
0000 0000 0000 0000 0000 0000 0110 0101 
  • 同一个数&运算后还是本身

或运算符 |

两个位只要有一个为1,那么结果就是1,否则就为0

printFormat(101);
printFormat(101|101);
结果:
0000 0000 0000 0000 0000 0000 0110 0101 
0000 0000 0000 0000 0000 0000 0110 0101 
  • 同一个数|运算后还是本身

非运算符 ~

位为0,结果是1,位为1,结果是0

printFormat(101);
printFormat(~101);
结果:
0000 0000 0000 0000 0000 0000 0110 0101 
1111 1111 1111 1111 1111 1111 1001 1010 

异或运算符 ^

两个位相同则结果为0,否则结果为1

printFormat(101);
printFormat(32);
printFormat(101^32);
结果:
0000 0000 0000 0000 0000 0000 0110 0101 
0000 0000 0000 0000 0000 0000 0010 0000 
0000 0000 0000 0000 0000 0000 0100 0101 

位移

左移运算

左移运算符 << ,num << 1,相当于num乘以2

示例:101
printFormat(101);
printFormat(101<<1);
结果:
左移前:0000 0000 0000 0000 0000 0000 0110 0101 
左移后: 0000 0000 0000 0000 0000 0000 1100 1010 

示例:-101
printFormat(-101);
printFormat(-101<<1);
结果:
左移前:1111 1111 1111 1111 1111 1111 1001 1011 
左移后: 1111 1111 1111 1111 1111 1111 0011 0110 

  • 正数左移,二进制左边移除1位,右边补0

  • 负数左移,二进制左边移除1位,右边补0

右移运算

右移运算符 >> ,num >> 1,相当于num除以

示例:101
printFormat(101);
printFormat(101>>1);
结果:
右移前: 0000 0000 0000 0000 0000 0000 0110 0101 
右移后: 0000 0000 0000 0000 0000 0000 0011 0010 

示例:-101
结果:
右移前: 1111 1111 1111 1111 1111 1111 1001 1011 
右移后: 1111 1111 1111 1111 1111 1111 1100 1101 
  • 正数右移,二进制右边移除1位,左边补0

  • 负数右移,二进制右边移除1位,左边补1

无符号右移

无符号右移 >>>,忽略符号位,空位都以0补齐

无符号右移运算符和右移运算符是一样的,不过无符号右移运算符在右移的时候是补0的,而右移运算符是补符号位的

表示无符号右移,也叫逻辑右移,即若该数为正,则高位补0,而若该数为负数,则右移后高位同样补0

printFormat(101);
printFormat(101>>>1);
printFormat(-101);
printFormat(-101>>>1);
结果:
右移前: 0000 0000 0000 0000 0000 0000 0110 0101 
右移后: 0000 0000 0000 0000 0000 0000 0011 0010 
右移前: 1111 1111 1111 1111 1111 1111 1001 1011 
右移后: 0111 1111 1111 1111 1111 1111 1100 1101 

  • 正负数右移,左边补0

测试代码如下:

public class TestBase {
    protected void printFormat(int n){
        out(format(n));
    }
    protected void printFormat(long n){
        out(format(n));
    }
    protected void out(Object obj){
        System.out.println(obj);
    }
    protected void err(Object obj){
        System.err.println(obj);
    }
    protected String format(long n){
        return format(toBinaryString(n),64);
    }
    private String format(String str,int len){
        if (len > str.length()){
            str = String.format("%0"+(len - str.length())+"d",0)+str;
        }
        int i = 1;
        StringBuilder sb = new StringBuilder();
        for (char c:str.toCharArray()) {
            sb.append(c);
            if (i == 4){
                sb.append(" ");
                i = 0;
            }
            i++;
        }
        return sb.toString();
    }
    protected String format(int n){

        return format(toBinaryString(n),32);
    }
    /**
     * 输出int类型的二进制
     * @param n
     * @return
     */
    protected String toBinaryString(int n){
        return  Integer.toBinaryString(n);
    }

    /**
     * 输出long类型的二进制
     * @param n
     * @return
     */
    protected String toBinaryString(long n){
        return  Long.toBinaryString(n);
    }
}

以上是关于位运算基础的主要内容,如果未能解决你的问题,请参考以下文章

Java基础东西(按位操作运算)

Java基础-位运算

Python 基础1 - 位运算符

86/88汇编代码的执行调试

JSP 基础语法

Java位运算基础知识